1

次の Haskell コードは、式が Cons _ _ の形式に評価されるかどうかを確認しようとしているときに、最後の 2 行目でエラーを出します。Haskell のエラー メッセージは次のとおりです。「式コンテキストのパターン構文: _」私がやろうとしているのは、実行時に式の型をチェックすることです。これは、私が読んだことから、これをより適切にプログラミングできる可能性が高いことを意味しますか? しかし、私は初心者なので、それが私がやっていることなのかどうかはわかりません。特に、約 1 時間前からこれをやろうとしているからです。

data Val = Num Int | Nil | Cons Val Val
    deriving (Eq, Show, Read)

interpret_expr :: Prog -> Vars -> Expr -> Val
interpret_expr _ _ (Isnum NilE) = Num 0
interpret_expr _ _ (Isnum (ConsE _ _)) = Num 0
interpret_expr _ _ (Isnum (NumE _)) = Num 1
interpret_expr prog vars (Isnum expr)
    | interpret_expr prog vars expr == Nil = Num 0
    | interpret_expr prog vars expr == Cons _ _ = Num 0
    | otherwise = Num 1
4

2 に答える 2

8
interpret_expr prog vars (Isnum expr)
    | interpret_expr prog vars expr == Nil = Num 0
    | interpret_expr prog vars expr == Cons _ _ = Num 0
    | otherwise = Num 1

ガードの使用は無効です。(==)関数 (ここでは関数) をパターンに適用することはできません。つまり、(型クラスを使用してEq) something とを比較することはできませんCons _ _。パターン マッチを再度行う必要がありますが、次のコマンドを使用して実行できますcase .. of

interpret_expr prog vars (Isnum expr) = case interpret_expr prog vars expr of
    Nil -> Num 0
    Cons _ _ -> Num 0
    _ -> Num 1
于 2013-04-11T05:59:04.467 に答える
5

値が特定のコンストラクターのものかどうかを確認することはよくあることです。多くの場合、手書きの断片が次の形式で表示されます。

isCons (Cons _ _) = True
isCons _          = False

そしてそれは次のように使用されます:

| isCons (interpret_expr prog vars expr) = Num 0

これは、さまざまなソースからソースへの書き換えツールが機能を追加するほど一般的ですis[Some Constructor](例:deriveおよびDriFT)。私はテンプレート Haskell ソリューションに部分的です (TH が非常にクリーンまたは安定しているからではなく、外部ツールを実行する必要がないため)。ライブラリをインストールするとderive、コードは次のようになります。

import Data.Derive.Is
import Data.DeriveTH
import Language.Haskell.TH

data Val = ...
  deriving (Eq, Ord, Show)

$(derive makeIs ''Val)
于 2013-04-11T05:49:11.873 に答える