2017-12-20 21 views
0

基本的にはEitherとMaybeの2つのタイプのFunctorインスタンスに問題があります。EitherとMaybeで構成されるタイプのFunctorインスタンスの作成方法

data Tuple a b = Tuple a b 
data Primitive = String String | Boolean Boolean | Number Number | Null 
data JsonValue = Object (Map String JsonValue) | Array (List JsonValue) | Primitive 
type Path = List String 
data JsonGraphValue = JsonGraphObject (Map String JsonGraphValue) | Atom JsonValue | Ref Path | Error JsonValue | JsonPrimitive Primitive 

newtype JsonGraphRecResult a = JsonGraphRecResult (Either String (Tuple (Maybe a) (List Path))) 
instance jsonGraphRecResultFunctor :: Functor JsonGraphRecResult where 
    map f (JsonGraphRecResult (Right (Tuple (Just value) paths))) = JsonGraphRecResult (Right (Tuple (Just (f value)) paths)) 
    map f value = value 

上記のコードの最後にある「値」という単語を指す次のエラーが発生します。 JsonGraphRecResultは罰金コンパイル以下何とかタイプから任意の異なる理由

Could not match type 

    a1 

    with type 

    b0 


while trying to match type JsonGraphRecResult a1 
    with type JsonGraphRecResult b0 
while checking that expression value 
    has type JsonGraphRecResult b0 
in value declaration jsonGraphRecResultFunctor 

where b0 is a rigid type variable 
     a1 is a rigid type variable 

は、それは私にははっきりしていない:

newtype Blah a = Blah (Maybe a) 
instance blahFunctor :: Functor Blah where 
    map f (Blah (Just x)) = Blah (Just (f x)) 
    map f value = value 

gistために、「PureScriptを試してみてください」オンラインREPLに直接貼り付けることができますエラーを複製します。

答えて

0

問題を解明しました。入力値が正しい型ではないため、「左」の場合はマップ関数の入力値を単に戻すことはできません。ここに問題の簡略版があります。

-- This is wrong because value is a Functor a, whereas map must return Functor b 
map [email protected] f = value 

-- This is right, because even though both sides are Nothing, the right-hand side is a Maybe b vs. Maybe a 
map Nothing f = Nothing 
0

あなたのタイプに合わせてFunctorインスタンスを派生させることができます。しかし、あなたがあなたのTupleタイプ(または単にData.TupleからTupleを使用;-))のためにそれを導出する必要があり、最終的なタイプのインスタンスを導出する前に:

data Tuple a b = Tuple a b 
derive instance functorTuple :: Functor (Tuple a) 

をあなたはFunctorインスタンスが唯一のタイプのために定義することができます見ることができるように種類* -> *です。この場合、の「最後の位置」を占めるオーバータイプのmapを入力することができます。 trypurescript.org

newtype JsonGraphRecResult a = 
    JsonGraphRecResult (Either String (Tuple (List Path) (Maybe a))) 
derive instance functorJsonGraphRecResult :: Functor JsonGraphRecResult 

Hereが関連している対話型のスニペットので、あなたがプレイすることができます:あなたのJsonGraphRecResultあなたはそれが「最後の位置」の要件を満たすためにTuple内部年代の種類の順序を変更する必要があるため、インスタンスを導出するために

この実装では

あなたは、この導出メカニズムを使用できるため、より型クラスがあります:OrdEqGenericNewtype ...

Purescriptに追加導出オプションを持っていることを、この文脈で指摘することも価値がありますこれは「新タイプ導出」です。

derive newtype instance someClassMyType :: SomeClass MyType 

ニュータイプの導出が与えられたのnewtype内部型がすでにインスタンスを定義したクラスのインスタンスを導出するためのnewtype「ラッパー」で使用されます。たとえば、 - それはderivenewtypeキーワードが含まれているため、構文は少し異なっているのです。つまり、newtype T = T aがある場合、にインスタンスがあるすべてのクラスに対してTのnewtypeインスタンスを派生させることができます。

別の戦略もあります。Data.Generic.Repのいくつかの型クラスに対して定義されたメソッドの汎用実装を使用することもできます。これらの実装は、Genericクラスのインスタンスである型に使用できます...しかし、これはあなたがシリーズフィルの「Purescriptの24日」に導出に関する詳細な情報を見つけることができます全体のまた別の話;-)

です:

https://github.com/paf31/24-days-of-purescript-2016

関連する問題