2012-08-22 2 views
4

Данные, например. типа, какУдовлетворительные законы монады без конструктора типов

data Tree a = Branch (Tree a) (Tree a) 
      | Leaf a 

можно легко писать экземпляры для Functor, Applicative, Монады и т.д.

Но если «содержали» типа предопределен, например,

data StringTree = Branch StringTree StringTree 
       | Leaf String 

Я теряю возможность писать эти экземпляры.

Если бы я писать функции для моего StringTree типа

stringTreeReturn :: String -> StringTree 
stringTreeBind :: String -> (String -> StringTree) -> StringTree 
stringTreeFail :: String -> StringTree 
-- etc. 

, который удовлетворил законы монад, я мог еще сказать, что StringTree монада?

+7

Что привело бы к 'fmap (const())? –

+2

Вы можете даже сделать 'stringTreeFMap :: (String -> String) -> (StringTree -> StringTree)', но для того, чтобы действительно быть монадой в смысле теории категорий, вам нужно «join :: m (ma) -> ma ', который не подходит вообще. –

+0

Просто из любопытства, почему вы не можете просто определить: 'type StringTree = Tree String'? –

ответ

2

Нет. Вы смотрите на разницу между типа и вид. Упрощенно, что тип Haskell классифицирует типы, поэтому это уровень абстракции выше типов. ghci может помочь.

:type stringReturn 
stringReturn :: String -> StringTree 
:type Functor 
<interactive>:1:1: Not in scope: data constructor `Functor' 

Так сразу же, мы можем видеть, что функция, которая имеет тип, это совсем другое дело, чем тип, который имеет вид.

Мы также можем задать ghci о видах.

:kind Functor 
Functor (* -> *) -> Constraint 
:kind StringTree 
StringTree :: * 
:kind Tree 
Tree :: * -> * 

Виды использования * для переменных в их обозначениях. Из приведенного выше взаимодействия видно, что Functor ожидает тип, параметризованный по одному аргументу. Мы также видим, что StringTree не принимает никаких параметров, а Tree берет один.

Это длинный способ выразить и распаковать ваш вопрос, но, надеюсь, он показывает разницу между типами и видами.

+0

О, конечно, конечно - виды будут разными – amindfv

+0

Раздел «[Классы классов и перегрузка] (http://www.haskell.org/tutorial/classes.html)» из «Нежное введение в Haskell, версия 98» вкратце вводит _kind_, если это помогает. –

0

Нет, это не было бы монадой. Подумайте об этом, можете ли вы написать монаду m, так ли возможно только m String?

3

Tree a не монада, либо в целом, или для какой-либо конкретной a, Treeсама является монадой. Монада не является типом, это соответствие между любым типом и «монадической версией» этого типа. Например, Integer является типом целых чисел, а Maybe Integer является типом целых чисел в монаде Maybe.

Следовательно, StringTree, который является типом, не может быть монадой. Это не то же самое. Вы можете попытаться представить это как тип строк в монаде, но ваши функции stringTreeReturn и т. Д. Не соответствуют типам их монадических корреспондентов. Посмотрите на тип >>= в Maybe монады:

Maybe a -> (a -> Maybe b) -> Maybe b 

Второй аргумент является функцией от некоторых a к любого типа в Maybe монады (Maybe b).stringTreeBind имеет тип:

String -> (String -> StringTree) -> StringTree 

Второй аргумент может быть только функцией от String к монадической версии String, а не к монадической версии любого типа.

Следовательно, вы не можете сделать все, что вы можете сделать, для значений в произвольном монадическом типе до значений StringTree, поэтому его нельзя сделать экземпляром. Даже если бы вы каким-то образом восприняли его как монаду, все начнется неправильно, если общий монадический код ожидает, что он сможет использовать общие монадические операции способами, которые не имеют смысла для StringTree.

В конце концов, если вы думаете о нем, как «как» монада, потому что это в контейнере, который может вести себя так же, как монадические контейнеры String, проще всего сделать, это просто сделать общий контейнер любого типа (Tree a). Если вам нужна вспомогательная функциональность, которая зависит от того, что она является деревом строк, вы можете записать этот код как действующий только по значениям Tree String, и он будет успешно сосуществовать вместе с кодом, который работает в основном на Tree a.

Смежные вопросы