【问题标题】:Generic 'unwrap' function in Haskell?Haskell中的通用“解包”功能?
【发布时间】:2012-02-27 06:45:23
【问题描述】:

当我在一个值上使用fmap 时,它实质上是“取消装箱”该值,将函数应用于它,然后将其装箱。

例如:

-- returns Just 8
fmap (+3) (Just 5)

是否有任何函数可以在不将其装箱的情况下为我提供价值?

-- returns 8
fmap_2 (+3) (Just 5)

当然,我不知道这对数组有什么作用,但对于初学者来说,它对Eithers 和Maybes 很有用。我也可以用它轻松混合 Monad:

-- myfunc :: Maybe Int

-- if myfunc returned a Just, show it and then print it. Otherwise, print 'Nothing'.
putStrLn . fmap show $ myfunc

或者还有其他混合 Monad 的标准方法吗?

【问题讨论】:

  • 不,没有混合单子的标准方法。不可能有。单子不通勤。但是,一些 monad 可以以它们自己的特殊方式混合。封装这种特殊的单子混合方式的既定方法称为单子转换器。那里有几个 monad 转换器库和大量文献。只需谷歌“monad 转换器”。

标签: haskell


【解决方案1】:

要提取Maybe,请使用maybe

maybe 0 (+3) $ Just 5
>>> 8
maybe 0 (+3) Nothing
>>> 0

只有在获得Nothing 必须被视为异常情况时才应使用fromJust。不要养成在没有充分理由的情况下使程序崩溃的习惯。 MaybeEither 正是为了帮助您避免这种情况。

对于Either,有一个函数either

either (*2) (+2) $ Left 3
>>> 6
either (*2) (+2) $ Right 3
>>> 5

请注意,在正确的代码中,您不需要经常提取 monad。这就是它们的重点,Haskell 必须提供所有你可能需要的工具来处理一元值,就好像它们是被提取的一样。

【讨论】:

  • 还有fromMaybe :: a -> Maybe a -> a
【解决方案2】:

所有函子不能存在此函数。即使对于像Maybe 这样的简单的,如果你有Nothing,它也行不通。对于IO,这会让您在程序中执行任意 IO,并且绝对不安全。最后,对于一些稍微奇怪的函子(比如(->) e,它只是一个接受e 类型参数的函数),这甚至没有任何意义。

然而,对于某些函子的类型,这个函数是存在的。例如,有一个名为fromJust 的函数,其类型为Maybe a -> a。然而,如果你给这个函数传递一个Nothing,你会得到一个运行时错误。

因此,对于同样是 Functor 实例的某些类型,可能存在这样的函数,但对于 Functor 类本身没有意义。

【讨论】:

    【解决方案3】:

    导入 Control.Comonad (extract)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-15
      • 1970-01-01
      相关资源
      最近更新 更多