2017-05-29 13 views
1

次のコードが間違っているとは本当に分かりません。Haskellの厳格な型変数

data TypeA = TypeA 

class MyClass a where 
    myClassFunction :: a -> String 

instance MyClass TypeA where 
    myClassFunction TypeA = "TypeA" 

bar :: (MyClass a) => String -> a 
bar "TypeA" = TypeA 

私は次のエラーを取得:私はHaskellの型システムに関する重要な何かが欠けていることを恐れている

Couldn't match expected type ‘a’ with actual type ‘TypeA’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for bar :: MyClass a => String -> a 
      at test.hs:9:8 
    Relevant bindings include 
     bar :: String -> a (bound at test.hs:10:1) 
    In the expression: TypeA 
    In an equation for ‘bar’: bar "TypeA" = TypeA 
Failed, modules loaded: none. 

を。

+0

あなたの目標は何ですか? –

+0

@BartekBanachewiczは、主にHaskell型システムとダイナミックディスパッチを試しています(私はこれがここに当てはまるとは確信していません) – Saczew

+0

ダイナミックなディスパッチが必要なのは明らかです。 –

答えて

4
(MyClass a) => String -> a 

与えられた(MyClass Intが定義されていると仮定すると、再び)タイプIntの値を返すために、例えば、ありません、関数がそれから頼んだあらゆるa型を返すことができることを意味し。あなたの実装は、その制約を満たすの1つの特定のタイプを返します。これは、明示的なシグネチャを持つ、より明白です:はっきり

bar :: forall a. (MyClass a) => String -> a 

読む、それはMyClassを満たすあらゆるタイプaためだ、この関数は文字列を取り、その型の値を返します。 あなたのバージョンはexists aとなります。

+0

したがって、彼の質問に定義された署名OPはどのように実装されますか? – Glubus

+0

@Glubus私はそれも可能だとは思わない。 'MyClass'は' String'値を減らす方法を提供しますが、 'a'型の新しい値を作る方法を提供しません。問題の定義はここで間違っています。 –

+0

Haskellで「動的」ディスパッチのようなものを実装する方法はありますか?実行時に関数を選択したいということです。私はTypeA = ValueA |のように定義すれば最も簡単だと思います。 ValueB。私はちょうど興味がある。 – Saczew

3

関数型MyClass a => String -> a発呼者選択した(MyClassのインスタンスと)任意の型の値を返すことができる機能を示しています。明白な方法は、値TypeA