3

私自身の理解では、Haskell で 2 つの引数を取る関数を定義したいと考えています。両方とも整数、または両方とも文字です。次のように、引数の簡単な検査を行います。

foo 1 2 = 1
foo 2 1 = 0
foo 'a' 'b' = -1
foo _ _ = -10

これは、引数が Num 型か Char 型かがわからないため、コンパイルされないことがわかっています。しかし、次のように引数を多態的にすることはできません。

foo :: a -> a -> Int

それは、本体の Char (または Int) でなければならないと言っているからです。

Haskellでこれを行うことは可能ですか? カスタムタイプを作成することを考えましたか?何かのようなもの:

data Bar = Int | Char
foo :: Bar -> Bar -> Int

しかし、これも有効ではないと思います。一般に、Haskell の関数が明示的に 1 つの型であるか、型クラスにポリモーフィックであり、関数本体での特定の型の使用を禁止するかの中間点があるかどうかについて、私は混乱しています。

4

3 に答える 3

5

データ型を使用して、Either2 つの異なる型を格納できます。このようなものが動作するはずです:

foo :: Either (Int, Int) (Char, Char) -> Int
foo (Right x) = 3
foo (Left y) = fst y

したがって、Leftデータ コンストラクターの場合は 2Intを渡し、Rightコンストラクターの場合は 2 を渡しますChar。別の方法は、次のように独自の代数データ型を定義することです。

data MyIntChar = MyInt (Int, Int) | MyChar (Char, Char) deriving (Show)

Either観察すると、上記の型がデータ型と同形であることがわかります。

于 2014-12-25T01:21:50.600 に答える
5

これに型クラスを使用することを必ずしも推奨するかどうかはわかりませんが、少なくともこのようなことは可能です。

class Foo a where
    foo :: a -> a -> Int

instance Foo Int where
    foo 1 2 = 1
    foo 2 1 = 0
    foo _ _ = -10

instance Foo Char where
    foo 'a' 'b' = -1
    foo _ _ = -10
于 2014-12-25T01:59:43.020 に答える
3

できるよ

type Bar = Either Int Char

foo :: Bar -> Bar -> Int
foo (Left 1) (Left 2) = 1
foo (Right 'a') (Right 'b') = -1 
foo (Left 3) (Right 'q') = 42
foo _ _ = 10

など -Eitherデータ型は、2 つの型を混在させるためのものです。次のような独自の同様のタイプをロールバックできます

data Quux = AnInt Int | AChar Char | ThreeBools Bool Bool Bool

これは、代数データ型と呼ばれます。

(特定の文字と整数を一緒に混合すると便利な状況を考えるのに苦労しています。主に、データがどこにあり、どのタイプであるかを知ることは非常に役立ちます。)

そうは言っても、私は代数データ型をよく書きますが、具体的になりたくないので、ランダムなものを組み合わせるのではなく、実際のものを表す意味のある名前をそれらに付けます。非常に具体的または完全に一般的であることは有用です。間に のような型クラスがありEqます。タイプを持つ関数を持つことができます。これは、定義された任意のタイプのタイプを持つEq a => a -> [a] -> Boolことを意味します。等価関数を定義する限り、私が考えもしなかったデータ型に使用できるように、開いたままにします。a -> [a] -> Bool==

于 2014-12-25T01:27:15.343 に答える