Есть ли в Haskell способ ограничить монаду M a так, чтобы a удовлетворял ограничению класса типа?
Я перевожу пример вероятностного моделирования с F# на Haskell. Однако в Haskell я пропустил support, потому что он изменил бы data Distribution a на data (Ord a) => Distribution a. С этим изменением я получаю следующую ошибку:
...probabilisticModeling.hs:42:13:
Could not deduce (Ord a) from the context ()
arising from a use of `always'
at ...probabilisticModeling.hs:42:13-18
Possible fix:
add (Ord a) to the context of the type signature for `return'
In the expression: always
In the definition of `return': return = always
In the instance declaration for `Monad Distribution'
Действительно, тип always / return: (Ord a) => a -> Distribution a. Есть ли способ получить монаду Distribution, но наложить ограничение (Ord a) на эту монаду? Я пытался:
instance Monad Distribution where
(>>=) = bind
return :: (Ord a) => a -> Distribution a = always
Но получаю ошибку:
...probabilisticModeling2.hs:48:4:
Pattern bindings (except simple variables) not allowed in instance declarations
return :: (Ord a) => a -> Distribution a = always
Failed, modules loaded: none.
Так есть ли способ иметь монаду M a, но ограничить a таким ограничением, как Ord a?
Спасибо.





Насколько я понимаю, вы просто не можете этого сделать, потому что монада предназначена для обобщения по всем типам, а не для некоторого ограниченного подмножества типов, таких как (Ord a).
Вместо ограничения монадического типа M a вы можете просто ограничить функции, которые используют этот монадический тип, например,
foo :: Ord a => Int -> M a
Фактически, желательно сохранять типы как можно более общими и использовать классы типов только для ограничения функций.
и т.п.
Похоже, я столкнулся с известной проблемой в Haskell. Я нашел много обходных путей автор поиск в Google по запросу "ограниченные монады". Это решения кажется наименее разрушительным. Тем не менее, для моих целей это кажется излишним. Думаю, я сохраню монаду Distribution в целом и упростлю поддержку с помощью ограниченной функции, как это предлагает Revolucent.
Разве «наименее разрушительное» решение - это не просто частный случай свободной монады? (Я знаю, что это решение было опубликовано до повального увлечения бесплатными монадами).
Проверьте Библиотека Мартина Эрвига, PFP:
The PFP library is a collection of modules for Haskell that facilitates probabilistic functional programming, that is, programming with stochastic values. The probabilistic functional programming approach is based on a data type for representing distributions. A distribution represent the outcome of a probabilistic event as a collection of all possible values, tagged with their likelihood.
Я считаю, что вы можете сделать это с помощью языкового расширения
ConstraintKindsи пакетаConstraintKinds, см. здесь для ограниченной монады и здесь дляFunctorConstraint.