0

在haskell,我试过这个:

multi::(Num n)=>n->((a->a)->(a->a))
(multi 0) f x=x
(multi n) f x=(multi n-1) f (f x)

希望获得一个可以多次重复另一个功能的功能。在 ghci 我得到了这个:

[1 of 1] Compiling Main             ( pad.hs, interpreted )

pad.hs:2:8:
    Could not deduce (Eq n) arising from the literal `0'
    from the context (Num n)
      bound by the type signature for
                 multi :: Num n => n -> (a -> a) -> a -> a
      at pad.hs:1:8-35
    Possible fix:
      add (Eq n) to the context of
        the type signature for multi :: Num n => n -> (a -> a) -> a -> a
    In the pattern: 0
    In an equation for `multi': multi 0 f x = x

pad.hs:3:23:
    Could not deduce (Num ((a -> a) -> a -> a))
      arising from a use of `-'
    from the context (Num n)
      bound by the type signature for
                 multi :: Num n => n -> (a -> a) -> a -> a
      at pad.hs:1:8-35
    Possible fix:
      add an instance declaration for (Num ((a -> a) -> a -> a))
    In the expression: multi n - 1
    In the expression: (multi n - 1) f (f x)
    In an equation for `multi': multi n f x = (multi n - 1) f (f x)
Failed, modules loaded: none.

我是haskell的新手。我该怎么办?

4

4 回答 4

4

夫妇的事情。你不能检查Nums 是否相等。您可能正在寻找一个Int. 其次,您不需要围绕 multi 的括号,它是论点。以及其他一些格式。

multi :: Int -> (a -> a) -> a -> a
multi 0 f x = x
multi n f x = multi (n-1) f (f x)

您可以使这种类型签名更通用,但我们会坚持下去。但是你可以用高阶函数来写这整件事。

multi :: Int -> (a -> a) -> a -> a
multi n f a = foldl (\v _ -> f v) a [1..n]
于 2013-10-31T21:24:05.753 回答
2

你几乎做到了。一个最小的修复是在周围添加括号n - 1并删除签名:

(multi 0) f x=x
(multi n) f x=(multi (n-1)) f (f x)
于 2013-10-31T21:22:31.763 回答
2

我可以对您的程序进行编译的最小更改是:

multi::(Eq n, Num n)=>n->((a->a)->(a->a))
(multi 0) f x=x
(multi n) f x=(multi (n-1)) f (f x)

Num类型类不要求成员已经是 的成员,Eq因此我们也必须指定它。此外,我们希望n-1作为参数传递给multi.

这个问题通常在 Haskell 领域用iterate和完成!!

于 2013-10-31T21:25:24.510 回答
1

这里有几件事是错误的。

Num n并不意味着,这意味着类型类定义Eq n中没有Eq n => Num n约束。Num为了进行模式匹配,0您需要n类型是Eq. 我只是明确地将其更改为Int,没有理由在这段代码中具有额外的通用性。

接下来,应用于(multi n-1)然后减去.b 我还清理了代码并将括号放在正确的位置。multin1

multi:: Int -> (a -> a) -> a -> a
multi 0 _ x = x
multi n f x = multi (n-1) f (f x)

正如Cirdec 指出的那样,您可以使用iterate f a !! n.

编辑:

如果你想要做的是获得一个f应用n时间的函数,你可以做这样的事情。10用你想要重复的任何功能替换n和替换。(1+)(或只是部分适用multi

let f = foldr1 (.) (take 10 $ repeat (1+))
于 2013-10-31T21:25:58.417 回答