5

我正在寻找一种惯用的做事方式

moveMaybeCreature Nothing world = world
moveMaybeCreature (Just creature) world = moveCreature creature world

或者换句话说

if isJust c
    then doSomething (fromJust c) w
    else w

我以为我可以这样:

moveMaybeCreature c w = foldr moveCreature w (maybeToList c)

我可以不用转换Maybe Creature[Creature]吗?

4

3 回答 3

10

只要类型world和类型moveCreature (fromJust c) world相同,您就可以执行此操作。您可以使用maybe来自Data.Maybe.

 moveMaybeCreature = maybe id moveCreature

您在模式匹配的第一种方式也应该可以正常工作。

于 2012-10-26T04:27:14.527 回答
6

我支持使用该maybe功能的建议。你问这个问题是对的,因为这个一般的经验法则(不仅对你,而且对任何阅读它的新手):具有类似Maybe Foo -> BarMaybe Foo -> Maybe Bar直接定义的类型的函数是 Haskell 中的代码异味。您几乎从不想编写一个Maybe Foo以参数为参数的函数;你想要一个只接受 的函数Foo,并使用一个高阶函数来适应它Maybe Foo

假设你有一个函数f' :: Maybe Foo -> Maybe Bar。这通常可以重构为:

  1. f :: Foo -> Barfmap f :: Maybe Foo -> Maybe Bar;
  2. f :: Foo -> Maybe Bar(>>=f) :: Maybe Foo -> Maybe Bar

第一种情况有效,因为这是 的Functor实例Maybe

instance Functor Maybe where
    fmap f Nothing = Nothing
    fmap f (Just x) = Just (f x)

-- or this:
--     fmap f = maybe Nothing (Just . f)

第二种情况有效,因为这是 的Monad实例Maybe

instance Monad Maybe where
    return = Just
    Nothing >>= f = Nothing
    (Just x) >>= f = f x

-- or this:
--     mx >>= f = maybe Nothing f mx
于 2012-10-26T04:55:19.067 回答
3

这是另一个选项,更接近您的原始代码:

import qualified Data.Foldable as F

moveMaybeCreature = flip (F.foldr moveCreature)
于 2012-10-26T08:32:32.113 回答