在haskell中的函数定义中声明函数类型

时间:2016-05-10 20:23:21

标签: haskell

我刚开始学习哈斯克尔。我在函数定义中有一些declare函数类型的混淆。例如,如果我们想要定义一个foldr函数:

foldr :: (a->b->b)->b->[a]->b
foldr f v [] = v
foldr f v (x:xs) = f x (foldr f v xs)

因此,foldr(+)0 [1,2,3,4] = sum [1,2,3,4] = 10.

我的问题是:我可以将其更改为:

foldr :: (a->a->a)->a->[a]->a
 OR:
foldr :: (a->b->c)->x->[y]->z

我没有找到解释定义中字母选择/要求的地方。谢谢!

更新: 我测试了它:

 foldr :: (a->b->c)->x->[y]->z

得到以下错误:

   Couldn't match type `y' with `a'
  `y' is a rigid type variable bound by
      the type signature for folderr :: (a -> b -> c) -> x -> [y] -> z
      at test.hs:3:1
  `a' is a rigid type variable bound by
      the type signature for folderr :: (a -> b -> c) -> x -> [y] -> z
      at test.hs:3:1

如果将所有内容更改为a,则有效。我一定在这里错过了一些观点。

正如@ sepp2k的评论中所述。我使用以下简单示例进行了测试:

     folderr :: (a->b->b)->b->[a]->b
     folderr f v [] = v
     folderr f v (x:xs) = f x (folderr f v xs)


     myop :: Int -> Bool -> Bool
     myop x y | x > 0 = True && y
              | otherwise = False && y

folderr(myop)True [3,3,222] - >真正 folderr(myop)True [3,2,-1] - >假

所以a,b只意味着类型不同或不同。

1 个答案:

答案 0 :(得分:3)

类型变量的具体名称无关紧要,即类型a -> b -> cx -> y -> zfoo -> bar -> baz都完全等效。

重要的是您是多次使用相同的类型变量还是使用不同的变量。这是a -> ba -> a不同的类型。具体而言,a -> b更为通用,因为在具体类型Int -> IntString -> StringInt -> StringString -> Int中,a -> a仅匹配前两个(分别为a = Inta = String),而a -> b将匹配所有四个。