Chr*_*ski 3 haskell functional-programming
我偶尔遇到一个小问题,我有一组嵌套的case语句,这会很麻烦.是否有任何技术/模式可用于可能有一个函数列表(这将等同于示例的case ...语句),评估所有这些,并选择匹配模式的第一个(例如:) Right x?
我将它们放在列表中的具体问题是它们不一定是同一类型(我认为是单态性限制).例如以下内容:
let possibleTags = [
parse (parseFileReference) "file reference" xStr
, parse (parseGitDiffReference) "git diff tag" xStr
]
Run Code Online (Sandbox Code Playgroud)
产生以下错误:
• Couldn't match type ‘GitDiffReference’ with ‘FileReference’
Expected type: Either ParseError FileReference
Actual type: Either ParseError GitDiffReference
• In the expression:
parse (parseGitDiffReference) "git diff tag" xStr
In the expression:
[parse (parseFileReference) "file reference" xStr,
parse (parseGitDiffReference) "git diff tag" xStr]
In an equation for ‘possibleTags’:
possibleTags
= [parse (parseFileReference) "file reference" xStr,
parse (parseGitDiffReference) "git diff tag" xStr]
Run Code Online (Sandbox Code Playgroud)
abc :: Int -> String
abc = undefined
abc2 :: Int -> Float
abc2 = undefined
abc3 :: Int -> Int
abc3 = undefined
example :: Int -> Maybe String
example x = case abc x of
("yes") -> Just "abc"
("no") -> case abc2 x of
1.0 -> Just "abc2"
2.0 -> case abc3 x of
100 -> Just "abc3"
200 -> Nothing
Run Code Online (Sandbox Code Playgroud)
我理想地寻找类似下面的东西(不是有效的代码):
-- Psuedo code
example :: Int -> Maybe String
example =
if (abc x && "yes") then Just "abc"
if (abc2 x && 1.0) then Just "abc2"
if (abc3 x && 100) then Just "abc3"
Run Code Online (Sandbox Code Playgroud)
使用if条件的问题是我不能(据我所知)进行模式匹配,例如if (Just x).
翻译确切示例(保持非穷举模式匹配):
import Data.Foldable
example2 :: Int -> Maybe String
example2 x = asum tests
where
tests =
[ case abc x of
"yes" -> Just "abc"
"no" -> Nothing
, case abc2 x of
1.0 -> Just "abc2"
2.0 -> Nothing
, case abc3 x of
100 -> Just "abc3"
200 -> Nothing
]
Run Code Online (Sandbox Code Playgroud)
至少当结果为 时Maybe,这看起来像是该实例的一个明确的用例Alternative:
example x = ("abc" <$ guard (abc x=="yes"))
<|>("abc2" <$ guard (abc2 x==1))
<|>("abc3" <$ guard (abc3 x==100))
Run Code Online (Sandbox Code Playgroud)