Haskell中的函数定义(GHCİ)

时间:2012-07-06 08:04:17

标签: haskell

我是Haskell的初学者。这个表达有什么问题?:

Prelude> let { f op [] = [] ; f op (h:t) = op h : f op t }
Prelude> f (+) []
<interactive>:337:1:
    No instance for (Show (t0 -> t0))
      arising from a use of `print'
    Possible fix: add an instance declaration for (Show (t0 -> t0))
    In a stmt of an interactive GHCi command: print it

非常感谢您的支持。

4 个答案:

答案 0 :(得分:2)

功能(+)的类型为(+) :: Num a => a -> a -> a,功能f的类型为f :: (t -> a) -> [t] -> [a]

f需要一个参数的函数。

f (+1) []将是正确的

答案 1 :(得分:2)

推断您的函数具有以下类型:(x -> y) -> [x] -> [y]

(+)的类型为Num a => a -> a -> a。如果我们将(x -> y)视为xay,则此属性可以是a -> a类型的实例,因此一切正常。因此,f (+) []中的空列表必须是[a]类型,并且返回类型必须是[a -> a](当然所有这些都具有相同的Num a约束)。因此f (+) []正确计算了Num a => [a -> a]类型的空列表。

这一切都很好,但GHCi想要打印你的表达结果。无法打印Num a => [a -> a]类型的值,因为无法打印功能。这基本上是GHCi给你的错误:No instance for (Show (t0 -> t0))

您的功能或调用该功能并没有任何问题。只是它导致一个(空的)函数列表,你无法打印。如果您let绑定了它,那么您就不会收到错误,而且您可以继续使用Num a => [a -> a]通常所期望的任何内容。

答案 2 :(得分:1)

函数f的类型是:

Prelude> :t f
f :: (t -> a) -> [t] -> [a]

如果你这样调用这个函数:

Prelude> f (+) []

...你得到了类型(让我们假设(+)仅适用于此示例中的Int):

(+) :: Int -> Int -> Int
(t -> a) = (Int -> (Int -> Int))
t = Int
a = (Int -> Int)

这意味着f的第二个参数的类型为[t] = [Int],返回类型为[a] = [Int -> Int]。因为返回类型是一个函数列表,并且无法显示函数,ghci将因类型错误而拒绝“编译”表达式,并且您会看到错误。

答案 3 :(得分:1)

f (+) []函数返回一系列函数:

Prelude> :t f (+) []
f (+) [] :: Num t => [t -> t]

并尝试在结果列表的每个元素上调用show函数,但函数不是Show类类的实例。