Поскольку вы добавили этот вопрос с 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
неверен.
Элегантный способ был опубликован ниже. Тем не менее, я хочу напомнить, что использование 'isJust/fromJust' является, пожалуй, наименее элегантным. В самом деле, если вы забудете проверку 'isJust',' fromJust' может привести к сбою вашей программы. Лучше всего было бы использовать сопоставление шаблонов, например, 'case f x of Nothing -> Nothing; Просто y -> Просто $ g y'. Также см. [Boolean blindness] (https://existentialtype.wordpress.com/2011/03/15/boolean-blindness/) для получения дополнительной информации. – chi
Это не правильный тип. 'g (fromJust (f x)): a'. Я думаю, что вы написали 'Just (g (fromJust (fx))'. –