`ord a =>`または `num a =>`
-
27-10-2019 - |
質問
次の機能があります。
which (x:xs) = worker x xs
worker x [] = x
worker x (y:ys)
| x > y = worker y ys
| otherwise = worker x ys
そして、これらの上記の機能のタイプの署名をどのように定義すべきか疑問に思っています which
と worker
?
たとえば、次の方法のどれが最高になるでしょうか 署名を入力します 労働者のために?
worker :: Num a => a -> [a] -> a
,
また
worker :: Ord a => a -> [a] -> a
?
私は本当に混乱しているだけで、これらの3つを選択すべきものを取得しません。あなたの考えに感謝します。ありがとう。
解決
明示的なタイプの署名なしで関数を定義する場合、Haskellは最も一般的なものを推測します。確信が持てない場合、これはあなたの定義がどのように読まれるかを把握する最も簡単な方法です。その後、ソースコードにコピーできます。よくある間違いは、関数を誤って入力してから、他のどこかで混乱するタイプのエラーを取得することです。
とにかく、あなたはで情報を得ることができます Num
タイピングによるクラス :i Num
GHCIに、またはドキュメントを読むことによって。 Num
クラスはあなたに与えます +
, *
, -
, negate
, abs
, signum
, fromInteger
, 、およびすべての機能 Eq
と Show
. 。それに注意してください <
と >
ありません!の値が必要です Num
そして、それらを比較しようとすると、実際にはタイプエラーが生成されます。すべての種類の数を比較できるわけではありません。
だからそうあるべきです Ord a => ...
, 、 なので Num a => ...
試した場合、タイプエラーが生成されます。
他のヒント
あなたの機能が何をするかを考えると、あなたはそれを見るでしょう which xs
で最小値を返します xs
. 。最小値は何ですか?何かのリスト Ord
エアブル!
GHCIに尋ねて、それが言っていることを見てください。私はあなたのコードをファイルにコピーして、それをGHCIにロードしました。それから私は使用しました :t
これは、何かのタイプを決定するための特別なGHCIコマンドです。
ghci> :t which
which :: (Ord t) => [t] -> t
ghci> :t worker
worker :: (Ord a) => a -> [a] -> a
Haskellのタイプの推論は、ほとんどの場合、かなり賢いです。それを信頼することを学ぶ。他の答えはその理由を十分にカバーしています Ord
この場合に使用する必要があります。私は、GHCIが何かの種類を決定するためのテクニックとして明確に言及されていることを確認したかっただけです。
私はいつもORDタイプの制約を使用します。最も一般的なので、より頻繁に再利用できます。
ORDよりもnumを使用することに利点はありません。
INTは多型ではなく、辞書の検索を必要としないため、小さな利点がある場合があります。私はordを使用して、パフォーマンスに必要な場合は専門的なプラグマを使用します。
編集:コメントの後に私の答えを変更しました。
それはあなたが比較できるものに依存します。比較できるようにしたい場合 Double
, Float
, Int
, Integer
と Char
次に、使用します Ord
. 。比較できるだけの場合 Int
次に、使用してください Int
.
このような別の問題がある場合は、タイプクラスのインスタンスを見て、関数で使用できるタイプを表示してください。