Что значит ! означает в определении записи перед типом поля? [Дубликат]

Я думаю, что вам не хватает расширения .exe. Ваш путь должен быть таким

System.setProperty("webdriver.gecko.driver", 
    "/usr/local/bin/geckodriver.exe");
218
задан svick 19 April 2014 в 21:49
поделиться

3 ответа

Это декларация строгости. В основном это означает, что при создании значения структуры данных она должна быть оценена так называемой «слабой нормальной формой головы». Давайте посмотрим на пример, чтобы мы могли видеть, что это значит:

data Foo = Foo Int Int !Int !(Maybe Int)

f = Foo (2+2) (3+3) (4+4) (Just (5+5))

Функция f выше, когда оценивается, вернет «thunk»: то есть код для выполнения чтобы выяснить его ценность. В этот момент Foo еще не существует, просто код.

Но в какой-то момент кто-то может попытаться заглянуть внутрь, возможно, через совпадение с шаблоном:

case f of
     Foo 0 _ _ _ -> "first arg is zero"
     _           -> "first arge is something else"

Это позволит выполнить достаточно кода, чтобы делать то, что ему нужно, и не более того. Таким образом, он создаст Foo с четырьмя параметрами (потому что вы не можете заглядывать в него без его наличия). Во-первых, поскольку мы тестируем его, нам нужно оценить весь путь до 4, где мы понимаем, что он не соответствует.

Второе не нужно оценивать, потому что мы «Не проверяйте его. Таким образом, вместо сохранения 6 в этой ячейке памяти мы просто сохраним код для возможной последующей оценки (3+3). Это будет 6, только если кто-то посмотрит на это.

Третий параметр, однако, имеет перед ним !, поэтому строго оценивается: (4+4) выполняется, а 8 ] сохраняется в этой ячейке памяти.

Четвертый параметр также строго оценивается. Но вот здесь это немного сложно: мы оцениваем не полностью, а только к слабой нормальной форме головы. Это означает, что мы выясняем, есть ли это Nothing или Just что-то, и сохраняем это, но мы не идем дальше. Это означает, что мы сохраняем не Just 10, а на самом деле Just (5+5), оставляя трюк внутри неоценимым. Это важно знать, хотя я думаю, что все последствия этого выходят далеко за рамки этого вопроса.

Вы можете аннотировать аргументы функции таким же образом, если вы включите расширение языка BangPatterns :

f x !y = x*y

f (1+1) (2+2) вернет thunk (1+1)*4.

264
ответ дан Curt J. Sampson 1 September 2018 в 00:52
поделиться

Простым способом увидеть разницу между строгими и нестрогими аргументами конструктора является то, как они ведут себя, когда они не определены. Учитывая

data Foo = Foo Int !Int

first (Foo x _) = x
second (Foo _ y) = y

Поскольку нестрогий аргумент не оценивается second, то передача в undefined не вызывает проблемы:

> second (Foo undefined 1)
1

Но строгий аргумент не может быть undefined, даже если мы не используем значение:

> first (Foo 1 undefined)
*** Exception: Prelude.undefined
73
ответ дан Chris Conway 1 September 2018 в 00:52
поделиться

Я считаю, что это аннотация строгости.

Haskell - это чистый и ленивый функциональный язык , но иногда накладные расходы на ленивость могут быть слишком много или расточительными. Поэтому, чтобы справиться с этим, вы можете попросить компилятор полностью оценить аргументы функции вместо того, чтобы разыгрывать шумы вокруг.

На этой странице есть дополнительная информация: Производительность / Строгость .

24
ответ дан Chris Vest 1 September 2018 в 00:52
поделиться
Другие вопросы по тегам:

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