0

次のコンストラクターがある場合:

data Garage = Gar String

タイプが私のガレージタイプと等しいかどうかをテストしたい場合は、次のようにします。

(==(Gar _)) (Gar "g")

ただし、コンパイラはアンダースコアについて文句を言います。これを置き換えると"g"、が返されますTrue。ワイルドカードと比較できる方法はありますか?

4

4 に答える 4

4

コードが機能しないのはなぜですか?

パターンマッチをしたいように見えますが、実際には==引数Gar _とを指定して関数を呼び出していますGar "g"。そのため、Haskell は混乱して、「式コンテキストのパターン構文: _」のようなことを言います。

どうすれば修正できますか?

あなたはできる:

  1. deriving Eqデータ宣言の最後に追加する、または

  2. 自分で実装しEqます:

    instance Eq Garage where
        (Gar l) == (Gar r) = l == r
    

コンストラクターのワイルドカードに対してパターン マッチを行うことは可能ですか? (完全を期すために)

はい、ここにナンセンス関数があります:

f :: Garage -> Int
f (Gar "abc") = 12
f (Gar _) = 4

ただし、これはおそらく、複数のコンストラクターを持つデータ型でより便利です。

于 2012-09-20T20:44:51.290 に答える
2

次のように、パターン マッチを実行します。

case x of
   Gar _ -> True
   _     -> False

関数として必要な場合は、次のようなものを追加します

isGarage (Gar _) = True
isGarage _       = False
于 2012-09-20T20:33:01.500 に答える
0

あなたの質問は、Haskell で実行時の型チェックを行う必要があると想定しているかもしれませんが、それは必須ではありません。Haskell は、コンパイル時にすべての型が正しいことを確認するため、データがGarageデータ型の一部であるかどうかをチェックする関数は必要なく、機能しません。

justPrintGarages (Gar x) = print x -- if the argument is a Garage, print its content
justPrintGarages _ = return ()     -- if it's anything else, do nothing.

ghci にどんな型justPrintGaragesがあるか尋ねると、答えてくれます

printGarages :: Garage -> IO ()

うわぁ!ガレージがあるかどうかを教えてくれるはずだった私たちの関数は、ガレージでしか機能しませんか??? うん。これは、Haskell が故意に型を混同しないようにするためです。これは実行時エラーの泥沼であるためです。静的型付けはあなたの友達です。静的型付けは苦痛の世界を取り除きます。静的型付けのため、定義できません

printGaragesAndShebangs (Gar x) = print x
printGaragesAndShebangs ('#':'!':xs) = putStr xs
printGaragesAndShebangs _ = return ()

型エラーが発生します。Strings とs を同じように扱うことはできませんGarage

ガレージと文字列を混在させたい場合は、型の安全性を保ちながら次のようにします。

data GarageStringInt = GsiG Garage | GsiS String | GsiI Int

(GarageStringIntは恐ろしい名前であり、GisGその他も同様ですが、コードでこれが必要な場合は、意味のあるものを表し (願っています)、それが何を表すかを説明する名前を付けることができます。)

今、私たちは書くことができます

printGaragesAndShebangs :: GarageStringInt -> IO ()
printGaragesAndShebangs (GsiG (Gar x)) = print x
printGaragesAndShebangs (GsiS ('#':'!':xs)) = putStr xs
printGaragesAndShebangs _ = return ()
于 2012-09-21T08:23:34.860 に答える
0

のような関数

isGarage (Gar _) = True
isGarage _       = False

type を持っているので、かなり役に立ちませんGarage -> BoolTrueそのため、型に対しては常に返されGarage、他の型に対しては型チェックの失敗が発生します。

あなたの要件にはパターンマッチングで十分だと思います。ただし、操作する型がわかっている場合は、型クラスを使用してそのような種類の関数を使用できることを示すためだけに。したがって、特定のタイプのセットから値を取得することがわかっている場合は、次のようなことができます

{-# LANGUAGE FlexibleInstances #-}
data Garage = Gar String

class IsGarage a where
    isGarage :: a -> Bool
    isGarage _ = False

instance IsGarage Garage where
    isGarage _ = True

instance IsGarage [Char]

ghciで

*Main> :t isGarage 
isGarage :: IsGarage a => a -> Bool
*Main> isGarage "3"
False
*Main> isGarage (Gar "2")
True
于 2012-09-21T08:48:19.357 に答える