以下代码说明了我的意图。我希望模式匹配,如果结果不是heroku run ls
,如果匹配结果为Nothing
Just something
还有其他方法data MyData =
A Int
| B String
| C
ifA (A i) = Just i
ifA _ = Nothing
ifB (B str) = Just str
ifB _ = Nothing
ifC C = Just ()
ifC _ = Nothing
mbMult3 i = Just (i*3)
concWorld str = Just (str ++ "World")
example1 v = ifA v >>= mbMult3
example2 v = ifB v >>= concWorld
-- example2 (B "Hello ,") == Just "Hello, World"
-- example2 (A 3) == Nothing
ifA
ifB
。
修改:
ifC
库可能有什么东西。但我现在对lens
一无所知。lens
答案 0 :(得分:5)
lens †。您可以使用makePrisms
为您的类型生成棱镜,然后使用^?
(或其前缀等效,preview
)来访问和类型的成员,如果不同则生成Nothing
值提供:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data MyData
= A Int
| B String
| C
deriving (Show)
makePrisms ''MyData
ghci> A 42 ^? _A
Just 42
ghci> A 42 ^? _B
Nothing
ghci> C ^? _C
Just ()
关于棱镜的好处是它们与其他光学元件组合(例如lenses,folds和traversals),并使用它们通过组合遍历嵌套的和类型棱镜:
ghci> (A 42, C) ^? _1._A
Just 42
ghci> (B "hello", C) ^? _1._A
Nothing
ghci> Just (A 42) ^? _Just._A
Just 42
ghci> Just (B "hello") ^? _Just._A
Nothing
ghci> Nothing ^? _Just._A
Nothing
lens包非常复杂,解释其所有功能都超出了本答案的范围。如果你不需要太多,你的解决方案可能很好。但是如果你发现自己编写了那么多代码,只要你愿意接受陡峭的学习曲线和经常混淆的类型错误,那么镜头很可能会有所帮助。
†更一般地说,^?
适用于产生零或一个值的任何Fold
(或更多,它只会忽略除第一个之外的所有值),但棱镜是专门设计的考虑到类型,所以它们在这里更相关。
答案 1 :(得分:0)
这是我不时使用的一个可爱的习语,因为我还没有使用我的镜头。
{-# LANGUAGE MonadComprehensions #-}
example1 v = [ x | A x <- pure v ] >>= mbMult3