4

2 つのパラメーターを受け入れ、最初のパラメーターが 2 番目のパラメーターの前に表示される必要がある場合は True、それ以外の場合は False を返す単純な min 関数を実装しようとしています。

min :: a -> a -> Bool
min a b = if a < b then True else False

私は得る:

No instance for (Ord a)
arising from a use of `<'
4

3 に答える 3

25

ドキュメントを見ると、の型(<)が次のように指定されていることがわかります。

(<) :: a -> a -> Bool

これは誤解を招く!

型宣言は、型クラス定義に表示されます。

class Eq a => Ord a where ...

したがって、フルタイプは

(<) :: Ord a => a -> a -> Bool

ちなみに、 ghci に type は何かと尋ねると、答えてくれます(<)

Prelude> :t (<)
(<) :: (Ord a) => a -> a -> Bool

また、同じ型クラスに , という関数が既に存在することに注意してくださいmin

min :: Ord a => a -> a -> a

minしたがって、元の を非表示にしない限り、関数を呼び出すことはできませんmin。(方法を説明するつもりはありません。代わりに、関数に別の名前を使用してください。)


最後に、あなたは今持っています

min :: Ord a => a -> a -> Bool
min a b = if a < b then True else False

Sarah が指摘しているように、if blah then True else Falseは と同じblahであるため、より明確に単純化できます。

min :: Ord a => a -> a -> Bool
min a b = a < b

現在、Haskell の演算子は変な名前の関数にすぎません --- これは

min :: Ord a => a -> a -> Bool
min a b = (<) a b

これをさらに単純化できます。

min :: Ord a => a -> a -> Bool
min = (<)

だから、あなたminはの別の名前です(<)<あなたの代わりにオリジナルを使用してみませんminか?

于 2012-04-11T14:42:00.030 に答える
8

これにはすでに2つの答えがありますが、重要な点が欠けていると思います:

型シグネチャが必要な理由(Ord a) =>、関数に「入れる」ことができる型を制限する必要があるためです。

function を定義するとき、関数は任意の型のデータを取り、同じ型の値を返すfunction :: a -> aと言っています。

これの良い例は次のとおりです。任意のhead :: [a] -> aタイプのリストが与えられた場合、 head はリストの最初の引数を返します。これは、 head が実際にはデータ自体に「接触」していないためです。そのため、それが何であるかはまったく問題になりません。

しかし、あなたの状況はそうではありません:データ型Countriesがあると想像してください:

data Countries = USA | Nigeria | China | Canada -- yes, I know there are a few missing

min USA Canadaまたはと言うのは意味がありませんUSA < Canada

したがって、関数をこの方法で比較できる型に制限する必要があります: Ord(つまり順序​​付けられた) 型クラスのインスタンスを持つ型です。それらを制限する方法は(Ord a) =>、型シグネチャの前に書くことです。

于 2012-04-11T15:54:42.803 に答える
7

動作させるには型制約が必要です<:

min :: Ord a => a -> a -> Bool
--     ^^^^^
于 2012-04-11T14:30:51.173 に答える