me2*_*me2 12 haskell coding-style
说我有
x = Just 2
Run Code Online (Sandbox Code Playgroud)
是否有一种方法(最好是内置机制/函数)在单个语句中使用x,这样如果它是Just,则自动解包并使用2,如果它是Nothing,则引发异常?
那是,
(f x) + 2 == 4if x == Just 2,如果是,则引发异常x == Nothing.
eph*_*ent 22
Data.Maybe.fromJust 其他答案已经提到:
fromJust :: Maybe a -> a
fromJust Nothing = error "Maybe.fromJust: Nothing"
fromJust (Just x) = x
Run Code Online (Sandbox Code Playgroud)
还有maybe(在发现Prelude和Data.Maybe):
maybe :: b -> (a -> b) -> Maybe a -> b
maybe n _ Nothing = n
maybe _ f (Just x) = f x
Run Code Online (Sandbox Code Playgroud)
fromJust可以用以下方式编写maybe:
fromJust = maybe (error "Maybe.fromJust: Nothing") id
Run Code Online (Sandbox Code Playgroud)
如您所见,maybe允许您灵活地处理两种情况而无需模式匹配:
\x -> maybe 0 (+ 2) x -- Nothing -> 0, Just 2 -> 4
Run Code Online (Sandbox Code Playgroud)
同样,Prelude并Data.Either有either :: (a -> c) -> (b -> c) -> Either a b -> c:
\x -> either (subtract 1) (* 2) x -- Left 5 -> 4, Right 3 -> 6
Run Code Online (Sandbox Code Playgroud)
如果定义数据类型
data MyDataType
= TypeA { foo :: Int, bar :: String }
| TypeB { foo :: Int, baz :: () }
| TypeC { bar :: String, baz :: () }
Run Code Online (Sandbox Code Playgroud)
像这样,你最终得到了访问器的部分功能.
foo :: MyDataType -> Int
bar :: MyDataType -> String
baz :: MyDataType -> ()
Run Code Online (Sandbox Code Playgroud)
它们被称为部分函数,而不是总函数,因为它们只返回其输入子集的结果.
foo (TypeA { foo = 15, bar = "hello!" }) -- 15
bar (TypeB { foo = 12345679, baz = () }) -- error
Run Code Online (Sandbox Code Playgroud)
对于这个特例,fromJust.一般来说
let Just k = x in f k + 2 == 4
Run Code Online (Sandbox Code Playgroud)
此技巧适用于任何数据类型构造函数,并且非常常用(:)于非空列表.