除了模式守卫之外,为什么不使用谓词守卫呢?

时间:2014-10-03 06:57:06

标签: haskell if-statement switch-statement predicate pattern-guards

除了模式守卫之外,为什么不使用谓词守卫呢?

{-# LANGUAGE MultiWayIf, LambdaCase #-}

module Main where

import System.Info         (os)
import Control.Applicative ((<$>))
import Data.Char           (toLower)
import Data.List           (isPrefixOf)

main :: IO ()
main = print . ($ toLower <$> os) $ \x -> if
  | "mingw" `isPrefixOf` x -> "windows"
  | "darwin" == x          -> "mac"
  | otherwise              -> "linux"

会更漂亮:

main = print $ case toLower <$> os of
  x | "mingw" `isPrefixOf` x -> "windows"
    | "darwin" == x          -> "mac"
    | otherwise              -> "linux"

甚至:

main = print $ case toLower <$> os of
  | ("mingw" `isPrefixOf`) -> "windows"
  | ("darwin" ==)          -> "mac"
  | otherwise              -> "linux" -- when pattern absent: otherwise = const True

2 个答案:

答案 0 :(得分:3)

您的第一个提案是有效的语法,所以只需使用它:

main = print $ case toLower <$> os of
  x | "mingw" `isPrefixOf` x -> "windows"
    | "darwin" == x          -> "mac"
    | otherwise              -> "linux"

答案 1 :(得分:0)

编辑:我认为你的目标是不惜一切代价获得一个无点的案例。正如AndrásKovács指出的那样,你的有意义的提议确实是正确的语法。

这是一场毫无意义的比赛:

{-# LANGUAGE ViewPatterns #-}
main = print $ case toLower <$> os of
  (("mingw" `isPrefixOf`) -> True) -> "windows"
  (("darwin" ==) -> True)          -> "mac"
  _                                -> "linux"

甚至没有视图模式:

match :: a -> [(a -> Bool, b)] -> b
match x ((f,y):rest) | f x       = y
                     | otherwise = match x rest
match _ [] = error "Non exhaustive predicates"

main = print $ match (toLower <$> os)
     [(("mingw" `isPrefixOf`) , "windows")
     ,(("darwin"==)           , "mac")
     ,((const True)           , "linux")]