>>> let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5 120This uses the fact that Haskell’s let introduces recursive bindings. We can rewrite this definition using fix,
>>> fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5 120Instead of making a recursive call, we introduce a dummy parameter rec; when used within fix, this parameter then refers to fix’s argument, hence the recursion is reintroduced.
isSuffixOf x y == reverse x `isPrefixOf` reverse yHowever, the real implemenation uses memcmp to compare the end of the string only, with no reverse required..
isSuffixOf x y == reverse x `isPrefixOf` reverse y
>>> "Hello" `isPrefixOf` "Hello World!" True
>>> "Hello" `isPrefixOf` "Wello Horld!" False
>>> "ld!" `isSuffixOf` "Hello World!" True
>>> "World" `isSuffixOf` "Hello World!" False
>>> stripPrefix "foo" "foobar" Just "bar"
>>> stripPrefix "foo" "foo" Just ""
>>> stripPrefix "foo" "barfoo" Nothing
>>> stripPrefix "foo" "barfoobaz" Nothing
>>> commonPrefixes "foobar" "fooquux" Just ("foo","bar","quux")
>>> commonPrefixes "veeble" "fetzer" Nothing
>>> commonPrefixes "" "baz" Nothing
>>> stripPrefix "foo" "foobar" Just "bar"
>>> stripPrefix "" "baz" Just "baz"
>>> stripPrefix "foo" "quux" NothingThis is particularly useful with the ViewPatterns extension to GHC, as follows:
{-# LANGUAGE ViewPatterns #-} import Data.Text as T fnordLength :: Text -> Int fnordLength (stripPrefix "fnord" -> Just suf) = T.length suf fnordLength _ = -1
>>> stripSuffix "bar" "foobar" Just "foo"
>>> stripSuffix "" "baz" Just "baz"
>>> stripSuffix "foo" "quux" NothingThis is particularly useful with the ViewPatterns extension to GHC, as follows:
{-# LANGUAGE ViewPatterns #-} import Data.Text as T quuxLength :: Text -> Int quuxLength (stripSuffix "quux" -> Just pre) = T.length pre quuxLength _ = -1
commonPrefixes "foobar" "fooquux" == Just ("foo","bar","quux") commonPrefixes "veeble" "fetzer" == Nothing commonPrefixes "" "baz" == Nothing