正确的未签名函数的类型签名

时间:2014-12-16 03:06:43

标签: haskell functional-programming currying

我正在学习Haskell中的函数的currying和uncurrying。 如果我有这个代码:

fc :: Num a =>  a ->  a ->  a -- curried function
fc x y  = x + y

fu :: Num a => (a, a) -> a --uncurried function
fu (x,y) = fc x y

uncurry' ::  Num a => (a -> a -> a) ->  Num a => (a, a) -> a
uncurry' f(x,y) = f x y

main = print(uncurry' fc 4 5)

编译器抱怨以下错误:

  

“非法多态或合格类型:Num a =>(a,a) - > a”。

uncurry'的正确类型签名是什么?

2 个答案:

答案 0 :(得分:7)

您只需要对类型签名设置一个约束:

uncurry' :: Num a => (a -> a -> a) -> (a, a) -> a
uncurry' f (x, y) = f x y

您不必在类型签名的中间添加额外约束,Haskell不喜欢这样。所有约束都在=>之前,并且只有一个约束应出现在类型签名中(直到启用某些编译器扩展,但这超出了本答案的范围)。

但是,正如jamshidh指出的那样,你可以使这个签名更加通用:

uncurry' :: (a -> b -> c) -> (a, b) -> c

它仍然可以正常工作。请记住,您总是可以强制签名从更一般到更不一般。

答案 1 :(得分:6)

一旦你发现了函数,它就是Num a=>(a, a)->a类型,所以你应该给它一个元组作为输入参数

main = print(uncurry' fc (4, 5))
但是,我会保持不受欢迎的类型。更一般的

(a -> b -> c) -> (a, b) -> c

一旦我做了这个改变,它对我有用。


哦,@ bheklilr发现了一些我甚至看不到的东西......他的修理加上我的修复应该让你起来......