Haskellのパターンマッチング文字列プレフィックス
-
05-07-2019 - |
質問
「Z」という文字で始まる文字列に一致する関数の特別なケースを作りたいとしましょう。次のようなことを行うことで、パターンマッチングを使用して簡単に実行できます。
myfunc ('Z' : restOfString) = -- do something special
myfunc s = -- do the default case here
しかし、より長いプレフィックスを持つ文字列に一致させたい場合はどうすればよいですか? 「トースター」という単語で始まる文字列の特殊なケースが必要だとします。このような文字列に一致するパターンを記述する最良の方法は何ですか?
解決
myfunc ('t':'o':'a':'s':'t':'e':'r' : restOfString) = ...
通常のパターンマッチを使用しても機能しますが、プレフィックス文字列が長くなると面倒になります。
{-# LANGUAGE PatternGuards #-}
import Data.List
myFunc string | Just restOfString <- stripPrefix "toaster" string =
-- do something special
myFunc string = -- do the default case here
パターンマッチの代わりにライブラリ関数を使用すると、読み取りと書き込みが少し簡単になります。
{-# LANGUAGE ViewPatterns #-}
import Data.List
myFunc (stripPrefix "toaster" -> Just restOfString) = -- do something special
myFunc string = -- do the default case here
GHC 6.10構文拡張により、この使用法がさらに自然になります。
もちろん、後者の2つは完全に同等であり、砂糖をまったく使用せずに(乱雑に)実行できます。
import Data.List
myFunc string =
if restIsJust
then -- do something special
else -- do the default case here
where
(restIsJust, restOfString) =
case stripPrefix "toaster" string of
Just something -> (True, something)
Nothing -> (False, undefined)
これらの構文拡張は、私たちにとって生活を楽にするためのものです。
他のヒント
import Data.List
myFunc str | "toaster" `isPrefixOf` str = something restOfString
| otherwise = somethingElse
where Just restOfString = stripPrefix "toaster" str
分割ライブラリ、 http://hackage.haskell.org/packages/archive/split/0.1.1/doc/html/Data-List-Split.html には、プレフィックス一致など、文字列を文字列で分割するための多くの機能があります。そこで役に立つものが見つかるかもしれません。
myfunc ('t' : 'o' : 'a' : 's' : 't' : 'e' : 'r' : restOfString)
私が知る限り、それ以上の簡潔な構文はありません。
もちろん、文字列がガード句のtoasterで始まるか、関数本体の if
で始まるかを確認することもできます。
myFunc str =
case stripPrefix "toaster" str of
Just restOfString -> something restOfString
Nothing -> somethingElse
これがstripPrefixがMaybe型を返す理由です。
所属していません StackOverflow