2015-12-17 9 views
5

私はhaskellの関数型言語のインタプリタを作成しようとしています(私はその言語を使い慣れていません)。抽象的なデータ型ではないが、私はおそらく微妙なものと便利なものを混ぜ合わせたものを作り出しているが、同種のリストを作る能力を提供したい。Haskellで言語を実装する:同質のリスト

私の基本的な変数はdata Datum = DatInt Int | DatDbl Double | DatBool Boolであり、私は均質なリストをどのように表現するのか全く分かりません。コンストラクタList Datumなどを追加すると、異種のリストが作成され、タイプごとに別のリストを作成すると、ListInt [Int] | ListDbl [Double]はリストのリストを除外します。

同種のリストを表現する最良の方法は何でしょうか?

+4

それは、原理的には同様異質なものを保持することができた場合でもあなたは、均質なリストの '一覧[データム]を'使用することができます。

今、あなたはこのような何かを型注釈付きの式を表すことができます。そのようなリストが均質であることを_statically_保証するには、おそらくGADTと存在する可能性のあるタイプが必要になるでしょう。あなたがハスケルを初めて習得したのなら、おそらくより単純な非静的保証の方法で通訳者を終わらせる方が良いでしょう。あなたが冒険的な気持ちになれば、より魅力的なタイプに移行することができます。 – chi

+2

実際、あなたの現在のフレームワークは、あらゆる型保証をエンコードする機会をあなたに与えるものではありません。 'Function'コンストラクタを追加すると、正しいタイプに関数が適用されているかどうかを確認することができなくなります。 – dfeuer

+0

@chi私は静的型保証を提供したい、理想的には言語拡張に頼る必要はありません。まったく可能ですか? – drowdemon

答えて

5

セクシーなタイプであろうとそうでなくても、有用な概念の1つはタイプタグです。非セクシーなバージョンは、扱いがずっと簡単です。

data Tag = IntTag 
     | DoubleTag 
     | BoolTag 
     | ListTag Tag 
    deriving (Eq, Show) 

あなたのタイプは、これらのさまざまなタグで表されます。 Intは、IntTagで表されます。 IntのリストはListTag IntTagで表されます。

data Expr = IntLit Int 
      | DoubleLit Double 
      | BoolLit Bool 
      | ListLit Tag [Expr] 

-- Check that an expression is validly annotated 
typeCheck :: Expr -> Maybe Tag 
typeCheck IntLit{} = Just IntTag 
... 
typeCheck (ListLit tag els) 
    | all good els = Just (ListTag tag) 
    | otherwise = Nothing 
    where 
    good el = case typeCheck el of 
       Nothing -> False 
       Just res = res == tag 
+2

これを適切に拡張できるようにするためには、 'checkType :: Type - > Expr - > Maybe()'と 'inferType :: Expr - > Maybe Type'の2つの関数が必要であると考えて、' inferType(ListLit tag els) = mapM_(checkTypeタグ)els >> return(ListTagタグ) '' checkType(ListTag t)(ListLit t 'els)=ガード(t == t')>> mapM_(checkType t)els; checkType _ ListLit {} =なし ' – user2407038

+1

バリアント: 'good el = typeCheck el == Justタグ'。 – chi

関連する問題