Почему Haskell не перечисляет причину пониманий ошибка, когда соответствие шаблона перестало работать?

Эти ответы (помимо решения Фреда Гандта) являются либо неправильными, либо неполными.

Предположим, что мне нужно variableName; присвоить значение undefined, и поэтому оно было объявлено таким образом, как var variableName;, что означает, что он уже инициализирован; - Как я могу проверить, объявлено ли это ранее?

Или даже лучше - как я могу сразу проверить, существует ли «Book1.chapter22.paragraph37» с одним вызовом, но не вызывает опорную ошибку?

Мы делаем это, используя самый мощный оператор JasvaScript, оператор in.:

"[variable||property]" in [context||root] 
>> true||false

. В периоды популярности AJAX я написал метод (позже названный) isNS (), который способна определять, существует ли пространство имен, включая глубокие тесты для имен свойств, таких как «Book1.chapter22.paragraph37» и многое другое.

Но поскольку он был ранее опубликован и из-за его большой важности он заслуживает чтобы опубликовать его в отдельном потоке, я не буду публиковать его здесь, но предоставит ключевые слова (javascript + isNS), которые помогут вам найти исходный код, поддерживаемый всеми необходимыми объяснениями.

20
задан Cybis 16 March 2009 в 04:34
поделиться

3 ответа

В то время как implemenatations Haskell не мог бы сделать этого непосредственно как это внутренне, полезно думать об этом этот путь:)

[x | Just x <- myList]

... становится:

do
    Just x <- myList
    return x

..., который является:

myList >>= \(Just x) -> return x

относительно Вашего вопроса:

то, Что я не понимаю, как Haskell знает для вызова функции "сбоя"?

В-нотации, если шаблон, связывающий сбои (т.е. Just x), то метод сбоя называют. Для вышеупомянутого примера это выглядело бы примерно так:

myList >>= \temp -> case temp of
    (Just x) -> return x
    _        -> fail "..."

Так, каждый раз у Вас есть соответствие шаблона в одноместном контексте, который может перестать работать, Haskell вставляет вызов в fail. Испытайте его с IO:

main = do
    (1,x) <- return (0,2)
    print x -- x would be 2, but the pattern match fails
31
ответ дан 29 November 2019 в 23:27
поделиться

Эти правило для desugaring понимание списка требует выражения формы [ e | p <- l ] (где e выражение, p шаблон, и l выражение списка) ведут себя как [1 120]

let ok p = [e]
    ok _ = []
in concatMap ok l

, Предыдущие версии Haskell имели понимания монады , которые были удалены из языка, потому что их было трудно считать и избыточный с do - нотация. (Понимания списка избыточны также, но их не настолько трудно считать.) Я думаю desugaring [ e | p <- l ] как , монада (или, чтобы быть точной, как монада с нулем ) привела бы к чему-то как [1 121]

let ok p = return e
    ok _ = mzero
in l >>= ok

, где mzero от MonadPlus класс. Это очень близко к [1 122]

do { p <- l; return e }

, который desugars к [1 123]

let ok p = return e
    ok _ = fail "..."
in l >>= ok

, Когда мы берем Монаду Списка, мы имеем

return e = [e]
mzero = fail _ = []
(>>=) = flip concatMap

, Т.е. 3 подхода (понимания списка, понимания монады, do выражения) эквивалентны для списков.

10
ответ дан 29 November 2019 в 23:27
поделиться

Я не думаю, что синтаксис понимания списка имеет непосредственное отношение к факту, который Список ([]), или Maybe в этом отношении, оказывается, экземпляр Monad класс типа.

понимания Списка действительно волшебство компилятора или сахар синтаксиса , но это возможно, потому что компилятор знает структуру [] тип данных.

Вот то, во что компилируется понимание списка: (Ну, я думаю, я на самом деле не проверял его по GHC)

xs = let f = \xs -> case xs of
                      Just x -> [x]
                      _      -> []
     in concatMap f myList

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

<час>

Интересно, это то, что синтаксис пониманий списка 'пропускает' отказы соответствия шаблона, используется в некоторых библиотеках, чтобы сделать универсальное программирование. Посмотрите пример в библиотека Uniplate .

<час>

Редактирование: , О, и отвечать на Ваш вопрос, Вы не можете назвать Ваш select функция с лямбдой, которую Вы дали ему. Это действительно перестанет работать при отказе соответствия шаблона при вызове его с Nothing значение.

Вы могли передать его эти f, функция от кода выше, но, чем [1 111] будет иметь тип:

select :: (a -> [b]) -> [a] -> [b]

, который прекрасно подходит, можно использовать эти concatMap функция внутренне:-)

кроме того, который новый select теперь имеет тип одноместного, связывают оператор для списков (с его зеркально отраженными аргументами):

(>>=) :: [a] -> (a -> [b]) -> [b]
xs >>= f = concatMap f xs -- 'or as you said: concat (map f xs)
6
ответ дан 29 November 2019 в 23:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: