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

きくらげ観察日記

好きなことを、適当に。

パターンマッチでTextを1文字ずつ処理する

PatternSynonymsのいい感じの実用例が思いついたので。

{-# LANGUAGE PatternSynonyms, OverloadedStrings, ViewPatterns #-}

import Data.Text

pattern c :+ cs <- (uncons -> Just (c, cs))

このパターンを定義することで、先頭文字がcで残りがcsであるようなTextにパターンマッチさせることができます。


使用例:

import Data.Char

numAlpha :: Text -> Int
numAlpha "" = 0
numAlpha (c :+ cs)
  | isAlpha c = 1 + numAlpha cs
  | otherwise = numAlpha cs

実行例:

>>> numAlpha "abc012def"
6

ただし、pattern synonymの定義にview patternを使っているため、このパターンはbidirectionalではありません。
したがって、例えば式中に

'a' :+ 'b' :+ 'c' :+ "def"

と書いたところで、これが

"abcdef"

になるわけではなく、単にコンパイルエラーになります。