😺
カリー化を試す
Haskellで「標準入力から読み込まれた二行の文字列の数値変換とそれらの加算結果を標準出力へ表示する」という処理を二つのパターンで記述します
文字列を数値変換するケースはよく見かけますが、計算を行うサンプルコードは記憶の中でも一件しか例がないので、試しに作ってみようという趣旨です
main::IO ()
main = putStrLn=<<id=<<(show.sum<$>).
(<$>((:[]).read<$>getLine))<$>
(:).read<$>(getLine::IO String)
こちらは配列パターン
main::IO ()
main = (\ [x,y]->((+)<$>x)>>=
(show<$>).(<$>y).id>>=putStrLn) $
(map (read<$>)) [getLine,getLine]
この二つのコードはカリー化を応用しています
カリー化とは引数が未適用状態の関数を戻り値に用いるテクニックです
数学では同型対応などと呼ばれます
Haskellでは標準でカリー化をサポートすることで一引数一戻り値の原則を徹底しています
そのおかげで関数を返すコードが書きやすい利点を持ちます
例えば足し算でカリー化を駆使すると以下の通りに書けます
main::IO ()
main=putStrLn.show.($ 1).(+) $ 1
尚冒頭の配列パターンをdo
に著すと以下のような形となります
main = do
let x=[do
a<-getLine
let b=read a::Int
return b,
do
a<-getLine
let b=read a::Int
return b,
do
n<-x!!0
m<-x!!1
return $ n+m]::[IO Int]
y<-do
a<-x!!2
return $ show a
putStrLn y
do
はIO a
を返す文脈なのでどこにでも書けて大変便利です
ランタイムに渡されない限り内部の手続きは一切評価されません
その反面処理を実行させたい場合はmain
で明示的な評価式を用意する必要から若干冗長になります
IO Int
同士は直接計算できないのでInt
の取得には工夫が必要です
Discussion