2

私には機能があり、dir_con :: (Int -> Dir)

特定のコンストラクター dir_con を見つけるためにパターン マッチを行いたいと考えています。データ型は次のとおりです。

data Dir = Define Int
         | Equals Int 
         | Data Int  
         | LCset Int
         | NoArg Int

したがって、dir_con は、Define、Equals などのいずれかになります。関数に渡され、次のようにパターン マッチが必要です。

case dir_con of
    NoArg -> Do something specific
    _     -> Do something for the rest

コンパイラはそれが好きではありません。エラー メッセージはCouldn't match expected type 'Int -> Dir' with actual type 'Dir'です。

確かNoArgにタイプのコンストラクター(Int -> Dir)ですか? Haskell はこのタイプのパターンマッチを許可していませんか? Dirコンストラクターはマップから取得されるため、これを行う必要があります。別の方法で治療する方法についての提案はありNoArgますか?

4

3 に答える 3

5

ふたつのやり方:

case dir_con of
    NoArg _ -> Do something specific
    _     -> Do something for the rest

コンストラクター関数ではなく /value/ に一致しています。

または、次のレコード構文を使用します。

case dir_con of
    NoArg {} -> Do something specific
    _     -> Do something for the rest

これは、フィールドの数に関して中立であるため、衛生的です。

于 2013-03-15T19:02:30.163 に答える
4

関数のパターン マッチはできません。type の値はDir、いくつかのコンストラクターの 1 つを適用することによって構築されますdir_conが、 type の関数ですInt -> Dir

おそらく、パターン マッチングの前に関数を適用する必要があります。

case dir_con 7 of  -- `7` is just an arbitrary value I'm passing
  NoArg _ -> ...
  _       -> ...

さらに、NoArgコンストラクターの引数も一致させる必要があります。そうしないと、引数を に追加した後に別の型エラーが発生しますdir_con

具体的な状況では、リテラル整数を渡したくない可能性が最も高いでしょうが、おそらく他の場所から取得した引数を渡したいと思うでしょう:

myfun n = ... case dir_con n of
                NoArg _ -> ...
                _       -> ...
于 2013-03-15T19:12:05.017 に答える
1

すべてのコンストラクターが type の場合Int -> Dir、@hammar と同じことをお勧めします: コンストラクターの型を列挙型にします。

data DirType = Define | Equals | Data | LCset | NoArg

data Dir = Dir DirType Int

DirType次に、代わりにそこの値を使用するのがどのコンストラクターであるかを知る必要があるものはすべてリファクタリングできます。

コンストラクターとは何かを判断しようとする際の本質的な問題dir_con :: Int -> Dirは、その型のすべてがコンストラクターであるとは限らないということです。例:

dispatch :: Int -> Dir
dispatch 0 = Define 0
dispatch 1 = Equals 1
dispatch n = NoArg n

「どのコンストラクター」が得られるかについての良い答えはありませんdispatch

Dirパラメトリックの場合

data Dir a = Define a | Equals a | Data a | LCset a | NoArg a

次に、Dirコンストラクターのタイプがあります。つまり(そのようなタイプを扱うには拡張機能forall a. a -> Dir aが必要です)。そのような型は、その引数を検査する{-# LANGUAGE RankNTypes #-}ような悪ふざけを許可しません。dispatchあなたが持っている場合:

dir_con :: forall a. a -> Dir a

次に、単純な値を渡すことでコンストラクターを検査できます

case dir_con () of
    ...

実質的に aしか使用しない場合でもDir Int、ポリモーフィズムにより、型をよりわかりやすくすることができます。

于 2013-03-15T22:26:24.877 に答える