アドホック多形関数とパラメトリック多形関数間を変換する一般的な方法があるのだろうかと思います。言い換えれば、アドホック多形関数を考えると、パラメトリックな対応をどのように実装するのでしょうか?他の方法はどうですか?アドホック多型関数とパラメトリック多形関数間を変換する良い方法
sort
を例にとります。それはsortBy
の面でsort :: Ord a => [a] -> [a]
を書くのは簡単です:
sort :: Ord a => [a] -> [a]
sort = sortBy compare
が、他の方法は、周りの私ができる最善のは、ビット「オブジェクト指向」に行くことです、これまで、トリッキーなようだ:
import qualified Data.List as L
data OrdVal a = OV (a -> a -> Ordering) a
instance Eq (OrdVal a) where
(OV cmp a) == (OV _ b) = a `cmp` b == EQ
instance Ord (OrdVal a) where
(OV cmp a) `compare` (OV _ b) = a `cmp` b
sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy cmp = map unOV . L.sort . map (OV cmp)
where
unOV (OV _ v) = v
をしかし、これは適切な解決策よりもハックに似ています。
ので、私は知りたいのです:この特定の例のためのより良い方法は
- がありますか?
- アドホック多型関数とパラメトリック関数を変換する一般的な技術は何ですか?
辞書を渡すことができれば(例:Agda implicitsのように)、これは簡単なことです。しかし、いくつかのクラス/ライブラリは、いくつかの不変量を保証するために辞書を渡すことができないという事実を利用していると私は信じています。たとえば、 'Data.Set.insert'を毎回違う順序で呼び出すことができると想像してみてください。 – chi
"ハック "は実際に動作しますが、2つの異なる' cmp'関数を ' OrdVal a 'の値。そうした場合、 'Ord'インスタンスは' Ord'法を満たしません。 – chi