2016-05-26 32 views
2

這個代碼是從https://wiki.haskell.org/Partial_application初學者Haskell - 如何實現這個功能?

採取我試圖實現這個功能:

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

請注意'comp2 == flip on',其中'on'在'Data.Function'中定義。 – chepner

回答

1

你確定你的意思是實現而不是使用? 如果你看comp2 :: (a -> b) -> (b -> b -> c) -> (a -> a -> c),可以看到comp2有兩個函數f和g。要使用comp2,你需要給它兩個函數,可能是兩個值。試試這個

comp2 (*2) (+) 2 3 
7

你已經實施comp2就好。你只是不要使用它是正確的。 comp2的參數都是函數。是3的一個功能?我不敢。

哈斯克爾編譯器有一個非常開放的心態,雖然– 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 

這還不是我們想要的那樣清楚,但它指出了問題:您嘗試使用函數類型作爲數字類型。