読者です 読者をやめる 読者になる 読者になる

IT練習ノート

IT関連で調べたこと(実際は嵌ったこと)を書いています。

再帰でのletとinが読み熟せない

99 problems 20より

別解として下記が示されていました。

removeAt :: Int -> [a] -> (Maybe a, [a])
removeAt _ [] = (Nothing, [])
removeAt 1 (x:xs) = (Just x, xs)
removeAt k (x:xs) = let (a, r) = removeAt (k - 1) xs in (a, x:r)

再帰しているので、letの値は再帰先から戻ってくるまで決まらないので、当然inの値も決まりません。
これを脳内でキープするのが難儀です。

具体例で書き下すとこんな感じでしょうか。

removeAt 3 “abcde” = let (a,r) = (removeAt 2 “bcde”                                 ) in (a     , ’a’:r    )
                   = let (a,r) = (let (a,r) = removeAt 1 “cde” in (a     , ’b’:r   )) in (a     , ’a’:r    )
                   = let (a,r) = (let (a,r) = (Just c “de")    in (a     , ’c’:r   )) in (a     , ’a’:r    )
                   = let (a,r) = (                             in (Just c, ’c’:"de”)) in (a     , ’a’:r    )
                   =                                                                  in (Just c, ’a’:"cde")

目線が、letとinを行ったり来たりするのが苦しいです。