Haskellの知識を深めたかったので、Hackageを適当に眺めて知らない型がないか探していました。今回はその中からDown
について調べたので、自分なりにメモしておこうと思います。
Down
Down
は逆順ソートなどに用いられる型のようです。Data.Ord
で定義されています。
SortOn
と組み合わせると、シンプルに逆順ソートを実装できます。
import Data.Ord
import Data.List
tekitou = [1,345,3,624,724,7,13,634,62,6,23,62,4562]
main = do
print (sortOn Down tekitou) --シンプルに書ける
print (sortBy (comparing Down) tekitou) --速度はこちらのほうが速いらしい
[4562,724,634,624,345,62,62,23,13,7,6,3,1]
[4562,724,634,624,345,62,62,23,13,7,6,3,1]
Down a
にはa
とは逆の大小関係が定義されています。以下、https://hackage.haskell.org/package/base-4.17.0.0/docs/src/Data.Ord.html より引用です。
-- | @since 4.6.0.0
instance Ord a => Ord (Down a) where
compare (Down x) (Down y) = y `compare` x
確かに、逆になっていますね。
Monad Down
Down
はMonad
のインスタンス(従ってFunctor
、Applicative
のインスタンス)です。以下、https://hackage.haskell.org/package/base-4.17.0.0/docs/src/Data.Ord.html より引用です。
-- | @since 4.11.0.0
instance Functor Down where
fmap = coerce
-- | @since 4.11.0.0
instance Applicative Down where
pure = Down
(<*>) = coerce
-- | @since 4.11.0.0
instance Monad Down where
Down a >>= k = k a
私はここで初めてcoerce
という関数を知りました。現状あまり理解していませんが、同じような型同士を変換する関数のようです。おそらくfmap = coerce
の場合、fmap f (Down x) = Down (f x)
と同じ意味だと思います。a
とDown a
はほとんど同じなので、自動的に変換できるということでしょうか。
一応do
記法でDown
がMonad
であることを見てみます。
import Data.Ord
f :: Num a => Down a -> Down a -> Down a
f x y = do
a <- x
b <- y
return (2*a+3*b)
main = do
let x = Down 1
let y = Down 2
print (f x y)
Down 8
Down
がMonad
のインスタンスであることはわかりましたが、Monad
のインスタンスであることを上手く利用した例はあるのでしょうか? (単に定義できるから定義しているだけ?)Monad
の具体例をなるべく多く知りたい気持ちがあるので、少し気になっています。