问题描述
这些区别是什么?
{ - #LANGUAGE RankNTypes# - }
f :: forall a。 a - > Int
f _ = 1
g ::(forall a。a) - > Int
g _ = 1
特别是,为什么我得到 g()
?
ghci> f()
1
ghci> g()
< interactive>:133:3:
无法与实际类型为'()'的预期类型'a'匹配
'a'是一个刚性类型变量,
a类型期望的上下文:a at< interactive>:133:1
在`g'的第一个参数中,即`()'
在表达式中:g()
在'it'的等式中:it = g()
ghci> f undefined
1
ghci> g undefined
1
f
只是一个普通的多态Haskell98函数,除了明确地写出 forall
以外。因此,签名中的所有类型变量都是调用者可以选择的参数(没有任何约束);在你的情况下,它解决了 a〜()
。
g
OTOH有一个2级的类型。它要求它的参数具有多态类型 forall a。一个
。 ()
没有这样的类型,它是单形的。但是 undefined
有这种类型(实际上, only 未定义和错误等),如果我们添加显式的 forall
也许它变得更清晰,Rank2函数更简单:
<$ p (显示a,数字a)=> a) - >字符串
h a =显示a1 ++:: Double \\\
++显示a2 ++:: Int
其中a1 :: Double; a2 :: Int
a1 = a; a2 = a
但我做不到
$ b
What is the difference between these?
{-# LANGUAGE RankNTypes #-}
f :: forall a. a -> Int
f _ = 1
g :: (forall a. a) -> Int
g _ = 1
In particular, why do I get an error with g ()
?
ghci> f ()
1
ghci> g ()
<interactive>:133:3:
Couldn't match expected type `a' with actual type `()'
`a' is a rigid type variable bound by
a type expected by the context: a at <interactive>:133:1
In the first argument of `g', namely `()'
In the expression: g ()
In an equation for `it': it = g ()
ghci> f undefined
1
ghci> g undefined
1
f
is just an ordinary polymorphic Haskell98 function, except the forall
is written out explicitly. So all the type variables in the signature are parameters the caller gets to choose (without any constraints); in your case it's resolved a ~ ()
.
g
OTOH has a rank-2 type. It requires that its argument has the polymorphic type forall a . a
. ()
does not have such a type, it is monomorphic. But undefined
has this type (in fact, only undefined, and error etc.), if we add the explicit forall
again.
Perhaps it becomes clearer with a less trivial Rank2 function:
h :: (forall a . (Show a, Num a) => a) -> String
h a = show a1 ++ " :: Double\n"
++ show a2 ++ " :: Int"
where a1 :: Double; a2 :: Int
a1 = a; a2 = a
but I can't do
这篇关于RankN'forall'的类型和范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!