我正在寻找一种惯用的做法
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]
的情况下执行此操作吗?
答案 0 :(得分:10)
只要world
和moveCreature (fromJust c) world
的类型相同,您就可以执行此操作。您可以使用maybe
中的Data.Maybe
。
moveMaybeCreature = maybe id moveCreature
你在模式匹配的第一种方式也应该工作得很好。
答案 1 :(得分:5)
我推荐使用maybe
功能。你提出这个问题是正确的,因为这个一般的经验法则(不仅适合你,而且适合任何阅读它的新手):直接定义Maybe Foo -> Bar
或Maybe Foo -> Maybe Bar
类型的函数是{ Haskell中的{3}}。你几乎不想写一个以Maybe Foo
为参数的函数;你想要一个只需要Foo
的函数,并使用一个更高阶的函数来使它适应Maybe Foo
。
假设您有一个函数f' :: Maybe Foo -> Maybe Bar
。这通常可以重构为:
f :: Foo -> Bar
和fmap f :: Maybe Foo -> Maybe Bar
; f :: Foo -> Maybe Bar
和(>>=f) :: Maybe Foo -> Maybe Bar
第一种情况有效,因为这是Functor
的{{1}}实例:
Maybe
第二种情况有效,因为这是instance Functor Maybe where
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
-- or this:
-- fmap f = maybe Nothing (Just . f)
的{{1}}实例:
Monad
答案 2 :(得分:3)
这是另一个选项,更接近原始代码:
import qualified Data.Foldable as F
moveMaybeCreature = flip (F.foldr moveCreature)