fmap 2-арная функция на Nothing должна возвращать Nothing? - PullRequest
0 голосов
/ 04 мая 2018

Из источника Maybe в ghc :

instance Functor Maybe where
    fmap _ Nothing  = Nothing
    fmap f (Just a) = Just (f a)

Когда fmap применяется к Nothing, должно возвращаться Nothing.

Например, запустите это в ghci (v8.2.2):

Prelude> fmap (+1) Nothing
Nothing

Однако, когда я применяю функцию с арностью 2:

Prelude> fmap (++) Nothing
<interactive>:11:1: error:
    • No instance for (Show ([a0] -> [a0]))
        arising from a use of ‘print’
        (maybe you haven't applied a function to enough arguments?)
    • In a stmt of an interactive GHCi command: print it

На самом деле результат выглядит как Nothing:

Prelude> import Data.Maybe
Prelude Data.Maybe> isNothing $ fmap (++) Nothing
True

У меня вопрос, действительно ли fmap (++) Nothing возвращает Nothing?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Да. Давайте посмотрим на типы:

fmap :: Functor f => (a -> b) -> f a -> f b
(++) :: [a] -> [a] -> [a]

так

fmap (++) :: Functor f => f [a] -> f ([a] -> [a])

fmap принимает функцию 1 арности. Однако в Haskell функция с 2 арностями - это просто функция с 1 арностью, которая возвращает другую функцию с 1 арностью:

([a] -> [a] -> [a]) ~ ([a] -> ([a] -> [a]))

твой fmap (++) :: Maybe [a] -> Maybe ([a] -> [a])

Если вы передадите Nothing, он вернет Nothing. Если вы передаете Just "foo" (например), он возвращает Just функцию, которая принимает строку и добавляет к ней "foo":

Prelude> Just f = fmap (++) $ Just "foo"
Prelude> f "bar"
"foobar"

Причина, по которой вы получаете ошибку, в том, что GHCi пытается распечатать вывод, то есть вывод должен реализовывать класс типов Show. show пытается Nothing :: Maybe ([a] -> [a]). Система типов не знает, что она просто должна печатать Nothing, все, что она знает, это то, что она не может show и [a] -> [a]. Так что печатает ошибку.

0 голосов
/ 04 мая 2018

Да, fmap f Nothing = Nothing независимо от того, что такое f или какого типа оно имеет. Экземпляр Show для Maybe выглядит как

instance Show a => Show (Maybe a) where
  ...

Таким образом, вы не можете show или print значение типа Maybe (A -> B), потому что у функций нет экземпляра Show.

...