ポイントフリースタイル

今日の一行 – ポイントフリースタイルを参考にして mytake から引数を消してみる。

mytake n xs = fst $ mysplitAt n xs
            ↓
mytake n xs = fst (mysplitAt n xs)
            ↓ 関数合成を使って xs を外に追い出す
mytake n xs = (fst . (mysplitAt n)) xs
            ↓ xs を消す
mytake n    = (fst . (mysplitAt n))
            ↓ 関数合成演算子を前置
mytake n    = (.) fst (mysplitAt n)
            ↓ もう一度,関数合成演算子を使って今度は n を追い出す
mytake n    = (((.) fst) . mysplitAt) n
            ↓ n を消す
mytake      = ((.) fst) . mysplitAt

結果。

*Main> mytake 2 [1,2,3,4]
[1,2]

おお!うまくいった!すごいな。
ポイントは関数合成とその演算子を前置するところだな。

んー,待てよ。単純にこうやったらどうだ?

mytake = fst . mysplitAt
*Main> :l mysplitAt.hs
Compiling Main             ( mysplitAt.hs, interpreted )

mysplitAt.hs:25:20:
    Couldn't match `(a, b)' against `t -> t1'
      Expected type: (a, b)
      Inferred type: t -> t1
      Expected type: Int -> (a, b)
      Inferred type: Int -> [a1] -> ([a1], [a1])
    In the second argument of `(.)', namely `mysplitAt'
Failed, modules loaded: none.

だめか。
そうか, (.) fst が関数を引数にとる関数で,これと mysplitAt を合成すると,mysplitAt の引数が外に追い出されるんだ。つまりこう。

mytake n xs = (((.) fst) . mysplitAt) n xs

で,引数が消える,と。

「ポイントフリースタイル」への1件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください