在没有无关代码的情况下在Haskell中展开数据类型

时间:2010-01-20 08:53:33

标签: haskell coding-style

说我有

x = Just 2

是否有一种方法(最好是内置机制/函数)在单个语句中使用x,这样如果它是Just,那么2将自动解包并使用,如果它是Nothing,则会引发异常?

即,

(f x) + 2 == 4 if x == Just 2,如果x == Nothing则引发异常。

3 个答案:

答案 0 :(得分:22)

Data.Maybe.fromJust已被其他答案提及:

fromJust :: Maybe a -> a
fromJust Nothing  = error "Maybe.fromJust: Nothing"
fromJust (Just x) = x

还有maybe(在PreludeData.Maybe中找到):

maybe :: b -> (a -> b) -> Maybe a -> b
maybe n _ Nothing  = n
maybe _ f (Just x) = f x

fromJust可以使用maybe编写:

fromJust = maybe (error "Maybe.fromJust: Nothing") id

如您所见,maybe允许您灵活地处理这两种情况而无需模式匹配:

\x -> maybe 0 (+ 2) x  -- Nothing -> 0, Just 2 -> 4

同样,PreludeData.Eithereither :: (a -> c) -> (b -> c) -> Either a b -> c

\x -> either (subtract 1) (* 2) x  -- Left 5 -> 4, Right 3 -> 6

如果您定义数据类型

data MyDataType
  = TypeA { foo :: Int, bar :: String }
  | TypeB { foo :: Int,                baz :: () }
  | TypeC {             bar :: String, baz :: () }
像这样,你最终得到了访问者的部分​​功能。

foo :: MyDataType -> Int
bar :: MyDataType -> String
baz :: MyDataType -> ()

它们被称为部分函数,​​而不是总函数,因为它们只返回其输入子集的结果。

foo (TypeA { foo = 15, bar = "hello!" })  -- 15
bar (TypeB { foo = 12345679, baz = () })  -- error

答案 1 :(得分:9)

对于这种特殊情况,fromJust。一般来说

let Just k = x in f k + 2 == 4

此技巧适用于任何数据类型构造函数,并且非常常用于(:)非空列表。

答案 2 :(得分:8)

fromJust应该做你想做的事。

相关问题