断言具有两个参数的函数的类型

时间:2017-03-10 22:08:17

标签: haskell

基本上,我正在做类似

的事情
c = a&&b

其中a,b都是Bool。

这是我写的:

c = a&&b (Bool a, Bool b) -> Bool

但显然它不起作用。任何人都可以说明问题是什么吗?

2 个答案:

答案 0 :(得分:4)

c = a&&b (Bool a, Bool b) -> Bool

这是语法错误。 a && b (Bool a, Bool b) -> Bool被视为单个表达式。如果我是编译器,我会抱怨->,因为那里没有效果。 (后续错误:Bool构造函数不在范围内,b不是函数。)

如果您想表达cBool

c :: Bool
c = a && b

如果您想表达a&&b表达式Bool

c = a && b :: Bool

但是,你的标题是" 带有两个参数的函数的类型"但是你的c不是一个函数(它没有参数)。如果您打算将ab作为参数,它将如下所示:

c a b = a && b

c = \a b -> a && b

在这种情况下,类型签名看起来像:

c :: Bool -> Bool -> Bool

这是因为某个类型中的->是正确关联的:Bool -> Bool -> Bool表示Bool -> (Bool -> Bool),即c是一个取Bool并返回函数的函数(需要Bool并返回Bool)。

c :: (Bool a, Bool b) -> Bool在多个级别上都是错误的。最直接的问题是Bool a是将参数传递给参数化类型的语法(如Maybe IntSet String),但Bool不带参数(如果它确实,然后... -> Bool会错过一个参数。)

其次,类型和表达生活在不同的世界"中。变量ab是这里的类型变量。它们与以下表达式中的ab无关。

第三,(X, Y)是元组语法。可以将c定义为采用单个参数(这是两个Bool s的元组):

c :: (Bool, Bool) -> Bool
c (a, b) = a && b

...但这不是通常在Haskell中完成的事情。惯例是更喜欢curried函数(上面描述的函数返回函数),你实际上有Arg1 -> Arg2 -> Arg3 -> ... -> Result

答案 1 :(得分:2)

您在单独的行上声明类型,如下所示:

c :: Bool -> Bool -> Bool
c a b = a && b

但是,你可以跳过这些论点:

c :: Bool -> Bool -> Bool
c = (&&)