【问题标题】:How type declarations in brackets work in Haskell like (Integer -> Integer) -> Integer括号中的类型声明如何在 Haskell 中工作,如 (Integer -> Integer) -> Integer
【发布时间】:2021-07-14 17:28:10
【问题描述】:

我是 Haskell 和编程的初学者。我正在学习如何根据类型声明编写函数。如何编写函数,哪些类型在括号中声明,如 (a -> b) -> b。

当我尝试这个时:

z :: (Integer -> Integer) -> Integer
z x y = x + y

我收到这样的错误:

    • Couldn't match expected type ‘Integer’
                  with actual type ‘(Integer -> Integer) -> Integer -> Integer’
    • The equation(s) for ‘z’ have two arguments,
      but its type ‘(Integer -> Integer) -> Integer’ has only one

如果我只给出一个分配给整数的参数,它会进行类型检查,

z f = 9

但不知道如何使用该功能,因为它在我输入 z 9 时显示错误:

  • No instance for (Num (Integer -> Integer))
        arising from the literal ‘5’
        (maybe you haven't applied a function to enough arguments?)
    • In the first argument of ‘z’, namely ‘5’
      In the expression: z 5
      In an equation for ‘it’: it = z 5

如何为此类类型声明编写适当的函数以及它们如何工作?

【问题讨论】:

  • 您的z 期望参数是一个函数。所以你对z 的实现没有多大意义,因为你在这里接受两个 参数,并且由于第一个是一个函数,如果你用x + y 实现它,它希望你可以将两个函数加在一起。
  • @WillemVanOnsem,感谢您的回复。因此,我是否需要分配函数以使函数返回整数,而不是分配 Integer ?
  • 可能会有所帮助,签名函数z :: (Integer -> Integer) -> Integer 的另一个示例是z f = f 42z 是一个将另一个函数作为其参数的函数,该函数将应用于 42。所以 z negate = -42z (+1) = 43z (*2) = 84

标签: haskell types type-systems


【解决方案1】:
z :: (a -> b) -> c

是接受a -> b 并返回c 的函数的签名;而a -> b 又是一个接受a 并返回b 的函数。

定义

z x y = x + y

与该类型不兼容。后一个函数确实有签名

z :: Num a => a -> a -> a

你可以认为和下面的一样

z :: a -> b -> c

在定义中使用+ 具有要求的效果

  • aNum
  • 并且bca相同。

当你写作时

z :: (Integer -> Integer) -> Integer
z f = 9

您正在定义一个函数z,它接受一个函数Integer -> Integer,根本不使用它,无论如何都返回9

所以你可以调用z (+3),即将函数“plus 3”传递给z,然后你就会退出9

事实上,每当您向z 提供可以被视为Integer -> Integer 的内容时,您都会得到9。这显然适用于z (+3)z (subtract 9) 等,但也适用于z undefined,因为undefined 具有undefined :: a 类型,即它可以代替任何类型,包括Integer -> Integer .

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2021-02-21
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多