2015-02-28 3 views
2

Итак, предположим, что мы хотим иметь дело с вычислениями, которые могут завершиться неудачно, используя контейнер, подобный Maybe. Если бы я был указать на то, что класс типов я хочу сделать, это было бы выглядеть примерно так:Обобщение isNothing

class Alternative f => Nullable f where 
    isEmpty :: f a -> Bool 

Такое, что isEmpty x == True тогда и только тогда, когда x = empty

Есть некоторые существующие класс типов, которые я должен использовать для этой функции или я должен просто использовать класс выше?

EDIT: Некоторые больше контекста

Я пытаюсь реализовать соответствие для логического программирования, и я хочу, чтобы иметь возможность иметь «не образец», т.е. «добиться успеха, если и только если эта программа не выполняется, то делать ___».

+1

Является ли 'Либо' считающимся допустимым? Значение 'Left 'Ошибка« на самом деле не является нулевым значением концептуально, существует только несколько типов, к которым это действительно может быть применено, если вы идете к концептуальному понятию обнуляемости. Вы можете посмотреть класс 'Control.Monad.Trans.Error.Error', который определяет' noMsg :: Error a => a' и 'strMsg :: Error a => String -> a', он очень похож на то, что вы хочу делать, а добавлять сообщения вместо простого логического флага для обнуления. – bheklilr

+0

'Либо a' является допустимым, если для любого типа a, имеющего разумное значение по умолчанию. Точка «Nullable» в моем сознании была скорее обобщением «Maybe», так что я мог написать код, который обычно находился бы внутри «Maybe», абстрагируясь от этого конкретного контейнера. Кроме того, 'Control.Monad ... Error' на самом деле не работает, поскольку я не могу проверить, является ли это ошибкой и каким-то образом обрабатывает ее. Я хочу подражать чему-то вроде «case x of (Just xs -> ...) (Nothing -> ...)' – gallabytes

+2

['Control.Monad.Error'] (https://hackage.haskell.org/package /mtl-1.1.0.2/docs/Control-Monad-Error.html) экспортирует некоторые структуры, чтобы помочь справиться с ошибками. Вы можете использовать 'catchError', чтобы обернуть блок операторов, который может вызывать' throwError' и обрабатывать ошибку. Я думаю, что это, вероятно, включает ваш «нулевой» прецедент, хотя у меня нет времени, чтобы выработать полный пример. –

ответ

5

Возможно, вы можете использовать Foldable таким образом. Maybe, [], Either, ErrorT, ExceptT все Foldable. Вы можете просто сопоставить шаблон по результату toList.

И в тех случаях, когда вы хотите что-то сделать с результатами успешного выполнения и ничего в случае сбоя, вы можете напрямую использовать forM_.

В качестве альтернативы вы можете использовать класс MonoidNull от monoid-subclasses, который обеспечивает предикат null.

+0

Или используйте 'foldMap' с' All' для определения 'null = getAll. foldMap (const $ All False) '. –

+1

@ PetrPudlák, почему не просто 'null = Data.Foldable.all (const False)'? Или дождитесь базы 4.8 :-) – dfeuer

+0

@dfeuer Правда, еще лучше :). Да, в базе 4.8 будет ['null :: (Foldable t) => ta -> Bool'] (https://hackage.haskell.org/package/base-4.8.0.0/candidate/docs/Data -Foldable.html # v: нуль). –

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