Subscribed unsubscribe Subscribe Subscribe

同じ文字をまとめる

Scheme
(pack '(a a a a b c c a a d e e e e))
((A A A A) (B) (C C) (A A) (D) (E E E E))

と結果が返ってくるような関数pack

同じ文字をまとめる - さかもっちゃんちゃんこ

Haskellで書いてSchemeに書き直してみた。

(use util.match)

(define (pack ls)
  (define (go x acc)
    (match acc
      ['() (list (list x))]
      [((y . ys) . zs)
        (if (equal? x y)
            (cons (cons x (cons y ys)) zs)
            (cons (list x) (cons (cons y ys) zs)))]))
  (fold-right go '() ls))

疑問。

  • Schemeでは、internal defineとletのどちらを使うのがベターなんだろう。
  • (list (list x))とかもっと簡単に書けないかな。
  • (cons (cons x (cons y ys)) zs)とか(cons (list x) (cons (cons y ys) zs))はもっと簡単に書けないかな。

元となったコード

pack :: Eq a => [a] -> [[a]]
pack = foldr go []
  where go :: Eq a => a -> [[a]] -> [[a]]
        go x []       = [[x]]
        go x yzs@(yys@(y:ys):zs)
          | x == y    = (x:yys):zs
          | otherwise = [x]:yzs
*Main> pack "aaaabccaadeeee"
["aaaa","b","cc","aa","d","eeee"]
*Main> let yzs@(yys@(y:ys):zs) = [['a']]
*Main> yzs
["a"]
*Main> yys
"a"
*Main> y
'a'
*Main> ys
""
*Main> zs
[]