Скажем, у меня есть функция:
f :: Int -> (Rational, Integer)
f b = ((toRational b)+1,(toInteger b)+1)
Я хочу абстрагироваться от (+1) следующим образом:
f :: Int -> (Rational, Integer)
f b = (h (toRational b)
,h (toInteger b))
where h = (+1)
Очевидно, это не сработает, но если я укажу сигнатуру типа, она сработает:
f :: Int -> (Rational, Integer)
f b = (h (toRational b)
,h (toInteger b))
where h :: Num a => a -> a
h = (+1)
Скажем, теперь я хочу еще больше абстрагировать функцию, передав h в качестве параметра:
f :: Num a => Int -> (a -> a) -> (Rational, Integer)
f b g = (h (toRational b)
,h (toInteger b))
where h :: Num a => a -> a
h = g
Я получаю сообщение об ошибке, что внутреннее a не совпадает с внешним a.
Кто-нибудь знает, как правильно написать эту функцию? Я хочу передать полиморфную функцию g
в f
и использовать ее полиморфно.
Я сталкивался с этой ситуацией несколько раз в самых разных проектах, и я не мог найти хорошего решения.
(+1)
полиморфен, только ужасный мономорфизм ограничение не позволяетh
наследовать эту черту. Если вы установите-XNoMonomorphismRestriction
, ваше второе поле кода будет работать нормально. - person leftaroundabout   schedule 14.02.2013