初学者Haskell - 如何实现这个功能?

时间:2016-05-26 21:23:43

标签: haskell

此代码取自https://wiki.haskell.org/Partial_application

我试图实现这个功能:

comp2 :: (a -> b) -> (b -> b -> c) -> (a -> a -> c)
comp2 f g = (\x y -> g (f x) (f y))

使用

*Main> comp2 3 4

但收到例外:

<interactive>:19:1:
    Non type-variable argument in the constraint: Num (a -> b)
    (Use FlexibleContexts to permit this)
    When checking that `it' has the inferred type
      it :: forall a b c.
            (Num (a -> b), Num (b -> b -> c)) =>
            a -> a -> c
*Main> 

如何实现comp2功能?

2 个答案:

答案 0 :(得分:7)

已实施 comp2就好了。你只是没有正确使用comp2的参数都是函数。 3是一个函数吗?我不敢。

Haskell编译器有一个非常开放的想法 - GHC认为a -> b 可能可能有一个Num实例(这是使用数字文字所需要的) )。因此,它不会给出Couldn't match type `a -> b` with numerical literal `3`之类的错误,但会继续假设必须是这样的实例,因为您正在调用它。但要实际搜索该实例,编译器需要启用FlexibleContexts

Prelude> comp2 3 4

<interactive>:9:1:
    Non type-variable argument in the constraint: Num (a -> b)
    (Use FlexibleContexts to permit this)
    When checking that ‘it’ has the inferred type
      it :: forall a b c.
            (Num (a -> b), Num (b -> b -> c)) =>
            a -> a -> c
Prelude> :set -XFlexibleContexts 
Prelude> comp2 3 4

<interactive>:11:1:
    Could not deduce (Num (a -> b0))
    from the context (Num (a -> b), Num (b -> b -> c))
      bound by the inferred type for ‘it’:
                 (Num (a -> b), Num (b -> b -> c)) => a -> a -> c
      at <interactive>:11:1-9
    The type variable ‘b0’ is ambiguous
    When checking that ‘it’ has the inferred type
      it :: forall a b c.
            (Num (a -> b), Num (b -> b -> c)) =>
            a -> a -> c
    Probable cause: the inferred type is ambiguous

这仍然不像我们所说的那样清晰,但它指出了问题:您尝试将函数类型用作数字类型。

答案 1 :(得分:1)

你确定你的意思是实施而不是使用? 如果你看一下comp2 :: (a -> b) -> (b -> b -> c) -> (a -> a -> c),就可以看到comp2有两个函数f和g。要使用comp2,您需要为它提供两个函数,可能还有两个值。试试这个

comp2 (*2) (+) 2 3