我是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
非常感谢您的支持。
答案 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)
视为x
而a
为y
,则此属性可以是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类类的实例。