2012-01-09 5 views
6

私はsome Arrow tutorialを経由していましたが、何らかの状態を維持しようとして新しいバージョンの関数を返す関数を使っていました。このように構成を定義すると何が問題になりますか?

新しい型がそのように定義されています。私は、私はそれ区分のインスタンスにする回路を構成することができるようにしたいので

newtype Circuit a b = Circuit {runCircuit :: a -> (b, Circuit a b)} 

。 2つの回路を構成する場合、その結果も回路でなければなりません。 (Circuit b c) . (Circuit a b)Circuit a cとなります。

私はこれを書いた:

import qualified Control.Category as Cat 
instance Cat.Category Circuit where 
    (Circuit g) . (Circuit f) = Circuit $ \a -> let 
                (b, new_f) = f a 
                (c, new_g) = g b 
                new_circ = new_g . new_f 
               in (c, new_circ) 

を、それは失敗します。

Main.hs:70:64: 
    Couldn't match expected type `b0 -> c0' 
       with actual type `Circuit b c' 
    In the first argument of `(.)', namely `new_g' 
    In the expression: new_g . new_f 
    In an equation for `new_circ': new_circ = new_g . new_f 

私はチュートリアルで答えを見て、この答えはうまくコンパイルされ、このような中間的機能を導入しました。

(.) = dot where 
    (Circuit g) `dot` (Circuit f) = Circuit $ \a -> let 
                 (b, new_f) = f a 
                 (c, new_g) = g b 
                 new_circ = new_g `dot` new_f 
                in (c, new_circ) 

私は違いを見ることができません。

答えて

10

.new_g . new_fは、序文のものであり、Control.Categoryのものではありません。したがって、Cat..を使用する必要があります。 Control.Categoryを使用する

しかし、通常の方法は次のとおりです。

import Prelude hiding (id, (.)) 
import Control.Category 
+0

パーフェクト、Cat.'だけで動作します '加えます。助けてくれてありがとう、私は今なぜ私たちがidと(。)を隠したいと思うかを見る。 – Niriel

関連する問題