如果模式与`Maybe a`结果匹配

时间:2018-01-21 09:14:29

标签: haskell lens

以下代码说明了我的意图。我希望模式匹配,如果结果不是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

修改:

  1. 我怀疑ifC库可能有什么东西。但我现在对lens一无所知。
  2. 更新了lens

2 个答案:

答案 0 :(得分:5)

来自Prisms包模型的

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 ()

关于棱镜的好处是它们与其他光学元件组合(例如lensesfoldstraversals),并使用它们通过组合遍历嵌套的和类型棱镜:

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