ポイントフリースタイル

今日の一行 - ポイントフリースタイルを参考にして 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

で,引数が消える,と。