Chinaunix首页 | 论坛 | 博客
  • 博客访问: 346564
  • 博文数量: 105
  • 博客积分: 2730
  • 博客等级: 少校
  • 技术积分: 1110
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-20 12:09
文章分类

全部博文(105)

文章存档

2013年(3)

2012年(2)

2011年(36)

2010年(34)

2009年(6)

2008年(20)

2007年(4)

分类: IT业界

2011-05-15 01:40:59

forall的意思就是数学中的"任取" ,没有更多含义级的东西了.看看haskell中的落实:


参考:
对于一般的泛型,forall都是隐含存在的.
启动forall的识别:
  ghci >:set -XExistentialQuantification
 .hs  {-# LANGUAGE ExistentialQuantification #-}

forall在函数定义时是隐含的:

map :: (a -> b) -> [a] -> [b]
map :: forall a b. (a -> b) -> [a] -> [b]
一个意思

但是在构造data定义的时候:
data SB = SB x
data定义需要具体类型,这时如果想让SB成为泛型(polymorphic), 就需要forall了,

> data SB = forall x. (show x) => SB x
> instance Show SB where
>   show (SB x) = show x
> x :: [SB]
> x = [SB 1, SB "xx",  SB ()]

这样, SB就是拥有Show属性的泛型了.
x可以show,虽然SB并不知道其中元素的具体类型,但是他们都是Show的实例,都可以被show函数处理.


Bool 是 集合{True,False,⊥}
Stirng 是集合{⊥,"a","b","ab",....}

这些类的交集只有{⊥}

[forall a. a] 表示列表里的每个元素都是(forall a. a)类型的, 包含的对象都是⊥
[forall a. Show a => a] 包含的对象拥有交集Show
forall a. [a] 表示列表元素可以是任意的东西,
  调用者可以把[a]看成任何的具体列表,注意这不是混合列表.

data T = forall a. MkT a  -- 只要有a,就有MkT a.
等价于:
MkT :: forall a. a -> T
heteroList = [MkT 5, MkT (), MkT True, MkT map]
data T' = forall a. Show a => MkT' a

ST monad是非常复杂的用于IO的monad
对应的函数:
runST :: forall a. (forall s. ST s a) -> a
(runST :: ST s a -> a)
两层的forall对应专业术语"rank-2 polymorphism"
ST可以被修改状态.
STRef表示对一个状态的引用,是ST内部的映射关系.
  newSTRef :: a -> ST s (STRef s a)
  readSTRef :: STRef s a -> ST s a
  writeSTRef :: STRef s a -> a -> ST s ()
对ST的操作就是从一些引用到一些值的操作, ST初始的时候就是空的引用和空的值.
如果使用不良的代码操作ST:
  let v = runST (newSTRef True)
  in runST (readSTRef v)
编译器在类型检查的时候:
    newSTRef True :: forall s. ST s (STRef s Bool)
    runST :: forall a. (forall s. ST s a) -> a
把两个第一个带入第二个:
**  together, forall a. (forall s. ST s (STRef s Bool)) -> STRef s Bool
里面的forall s.作用范围在括号内部,后面带入的(STRef s Bool),
    类型检测是就会说不匹配,因为它不被forall所涉及.
**  together, forall a. (forall s'. ST s' (STRef s' Bool)) -> STRef s Bool
注意, 里面很灵活,但是一旦返回了就会又受到限制.

--
定义灵活的数据类型:
newtype Pair a b=Pair (forall c. (a->b->c)->c)
可以定义函数类型返回任意的值,此时函数可以还没有出现!相当于接口/抽象.

阅读(1178) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~