Еще один новый ie вопрос в моей борьбе за изучение идиоматики c Haskell: Я пытаюсь составить умный конструктор из некоторых функций проверки, но не могу выровнять типы.
Это тип, который я хочу построить:
newtype Tag = Tag { getTag :: Text }
Это функции проверки:
validateCharacters :: Text -> Maybe Text
canonicalize :: Text -> Text
validateTagLength :: Text -> Maybe Text
А вот умный конструктор, который я пытаюсь написать :
mkTag t = Tag
<$> validateTagLength
>=> canonicalize
<$> validateCharacters t
Насколько я понимаю, типы должны складываться: canonicalize <$> validateCharacters
относится к типу Text -> Maybe Text
, как и validateTagLength
, а Kleisil fi sh должен объединять монади c функции a -> m b
. Наконец, сопоставление конструктора с результирующей монадой Maybe
должно вернуть ожидаемый Maybe Tag
. Однако я получаю следующие типы ошибок:
• Couldn't match type ‘Maybe Text’ with ‘Text’
Expected type: Text -> Text
Actual type: Text -> Maybe Text
• In the second argument of ‘(<$>)’, namely ‘validateTagLength’
In the first argument of ‘(>=>)’, namely
‘UnconstrainedTag <$> validateTagLength’
[...]
и
• Couldn't match expected type ‘b0 -> m c’
with actual type ‘Maybe Text’
• Possible cause: ‘(<$>)’ is applied to too many arguments
In the second argument of ‘(>=>)’, namely
‘canonicalize <$> validateCharacters t’
[...]
Где моя ошибка? Я упускаю какие-то правила приоритета?