1

我是 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

4 回答 4

2

函数(+)有类型(+) :: Num a => a -> a -> a,函数f有类型f :: (t -> a) -> [t] -> [a]

f期望一个参数的函数。

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

于 2012-07-06T08:09:32.760 回答
2

推断您的函数具有这种类型:(x -> y) -> [x] -> [y].

(+)有类型Num a => a -> a -> a(x -> y)如果我们采用xto beayto be ,这可以是该类型的一个实例a -> a,所以一切都很好。所以空列表f (+) []必须是 type [a],并且返回类型必须是[a -> a](当然,所有这些都具有相同的Num a约束)。所以f (+) []正确地计算了一个空的 type 列表Num a => [a -> a]

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

您的函数或对该函数的调用实际上没有任何问题。只是它会产生一个(空的)函数列表,您无法打印。如果您let改为绑定它,您将不会收到错误,并且您可以继续使用它来处理您通常期望能够使用Num a => [a -> a].

于 2012-07-06T08:19:54.863 回答
1

函数的类型f是:

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

如果你这样调用函数:

Prelude> f (+) []

...你得到了类型(让我们假设在这个例子中(+)只适用于s ):Int

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

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

于 2012-07-06T08:12:29.967 回答
1

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

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

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

于 2012-07-06T08:15:34.737 回答