我有兩個功能:組合(A - >也許一)和(a - > a)職能
f :: a -> Maybe a
g :: a -> a
我想創建這樣的功能:
h :: a -> Maybe a
h x
| isJust(f x) = Just (g $ fromJust(f x))
| otherwise = Nothing
我該怎麼辦呢以更優雅的方式?
我有兩個功能:組合(A - >也許一)和(a - > a)職能
f :: a -> Maybe a
g :: a -> a
我想創建這樣的功能:
h :: a -> Maybe a
h x
| isJust(f x) = Just (g $ fromJust(f x))
| otherwise = Nothing
我該怎麼辦呢以更優雅的方式?
既然你已經標記爲dot-operator這個問題:
h :: a -> Maybe a
h = fmap g . f
有關說明:
f :: a -> Maybe a
g :: a -> a
fmap g :: Maybe a -> Maybe a
(.) :: (Maybe a -> Maybe a) -> (a -> Maybe a) -> (a -> Maybe a)
(.) (fmap g) :: (a -> Maybe a) -> (a -> Maybe a)
fmap g . f :: (a -> Maybe a)
h :: a -> Maybe a
注意(.)
的和fmap g
的類型實際上是更普遍的:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
-- b in this case is Maybe a
-- c in this case is Maybe a
fmap g :: Functor f => f a -> f a
-- f in this case is Maybe
但是,你也可以對f
結果模式匹配:
h x =
case f x of
Just k -> Just (g k)
_ -> Nothing
請注意,您的原始示例甚至不會編譯,因爲g
的返回類型不正確。
我認爲這是最習慣的方式,並且表達了所有選項中最清楚的想法 – dfeuer
爲什麼不能簡單:
h :: a -> Maybe a
h x = fmap g (f x)
或運營商版本:
h :: a -> Maybe a
h x = g <$> f x
有
fmap2 :: (Functor g, Functor f) => (a -> b) -> g (f a) -> g (f b)
fmap2 = fmap . fmap
這裏是一個有趣的方式:
h :: a -> Maybe a
h = fmap2 g f
fmap2 g f ~> fmap (fmap g) f ~> fmap g . f ~> \x -> fmap g (f x)
的Functor ((->) r)
例如用在這裏:fmap
可以用來代替(.)
。
鑑於用戶(可能)是Haskell的新手,你會添加一些解釋嗎?不是每個人都熟悉'Functor(( - >)r)'。使用'b〜a','fa〜Maybe a'和'gc〜a - > c'會使這個更清晰 – Zeta
@Zeta,我想讓它看起來像一個謎題 – user3237465
因此,在'fmap。fmap'中左邊的'fmap'在'(a - >)'中,因爲'fmap g'總是一個函數,無論函數是什麼,右邊的'fmap'恰好在'Maybe'中(並且在owl combinator中,它也在(r - >)中。 –
優雅的方式發佈在下面。不過,我想提醒一下,使用'justJust/fromJust'可以說是最不優雅的方式。事實上,如果忘記「isJust」檢查,「fromJust」可能會導致程序崩潰。更好的方法是使用模式匹配來替代,例如沒有什麼 - >什麼都沒有;只是 - >只是$ g y'。另請參閱[布爾型失明](https://existentialtype.wordpress.com/2011/03/15/boolean-blindness/)瞭解更多信息。 – chi
這是不正確的類型。 g(來自Just(f x)):a'。我認爲你只是(g(fromJust(fx))' –