Какая область применения Haskell?
Я пытаюсь выяснить, использует ли Haskell динамическое или статическое определение.
Я понимаю, что, например, если вы определяете:
let x = 10
затем определим функцию
let square x = x*x
У вас есть 2 разных "х", и означает ли это, что они динамически охвачены? Если нет, то какая область применения используется и почему?
Кроме того, могут ли переменные Haskell иметь псевдонимы (другое имя для того же места/значения памяти)?
Спасибо.
Ответы
Ответ 1
В ваших утверждениях есть некоторые вещи...
- В Haskell нет переменных переменных (или неизменяемых переменных)
- Расположение переменной памяти - это понятие, которое не существует в Haskell
В вашем примере x не 10 в функции просто аргумент для квадрата, который может принимать любое значение (вы можете указать тип позже) в этом случае 10, но только в этом случае.
Вот пример псевдонимов, предоставленных Курт Сампсон:
import Data.IORef
main :: IO ()
main = do x <- newIORef 0 -- write 0 into x
readIORef x >>= print -- x contains 0
let y = x
readIORef y >>= print -- y contains 0
writeIORef x 42 -- write 42 into x
readIORef y >>= print -- y contains 42
Ответ 2
Haskell использует (в широком смысле) то же самое лексическое определение, что и большинство других языков.
например.
x = 10
Результаты в значении, указанном через x
в глобальной области, тогда как
square x = x * x
приведет к тому, что x
будет лексически привязано к квадрату функции. Это может помочь, если вы считаете, что указанная выше форма является синтаксической стилей для:
square = \ x -> x * x
Что касается вашего другого вопроса, я не уверен, что вы подразумеваете под псевдонимом
Ответ 3
Отвечая только на вторую часть вопроса:
У вас может быть несколько псевдонимов для одной и той же "ячейки памяти", но поскольку они все неизменяемы, это не имеет большого значения в большинстве случаев.
Немой пример:
foo x y = x * y
bar z = foo z z
Когда внутри foo
, вызванного из bar
, оба x
и y
явно имеют одинаковое значение. Но поскольку вы не можете изменять либо x
, либо y
, вы даже не заметите.
Ответ 4
Поскольку первая часть вопроса уже ответила другими, вот вторая часть:
Я предполагаю, что aliasing
вы имеете в виду one name for another
. Поскольку haskell является функциональным языком, а функции ведут себя как нормальные идентификаторы в любом случае, вы можете сделать это следующим образом:
y = x
который определит псевдоним y
для функции x
. Обратите внимание, что все является функцией. Даже если это выглядит как "переменная", это просто функция с нулевым значением, не принимающая аргументов. Псевдонимы для типов выглядят следующим образом:
type Function = Double -> Double
который будет определять псевдоним Function
для типа Double -> Double
Ответ 5
В вашем примере глобальное определение x затеняется локальным определением x. В Haskell переменная область определяется статическим чтением исходного кода - это называется лексической областью, но может получить что-то похожее на динамическое масштабирование с неявными параметрами (но это может привести к неожиданному поведению (я читал, никогда попробовал их сам)).
Ответ 6
Haskell использует статические вложенные области. То, что немного запутывает по сравнению с другими языками со статическими вложенными областями, заключается в том, что область имени - это блок, который включает тесты, предшествующие его определению. Например
evens = 0 : map (+1) odds
odds = map : (+1) evens
здесь имя "коэффициенты" находится в области определения "evens", несмотря на удивительный факт, что "коэффициенты" еще не определены. (Пример определяет два бесконечных списка четных и нечетных чисел.)
Мертвым языком с аналогичным областью определения правил был Modula-3. Но Haskell немного сложнее в том, что вы можете попытаться "переопределить" переменную в той же области, но вместо этого вы просто вводите другое уравнение рекурсии. Это ловушка для людей, которые сначала узнали ML или Scheme:
let x = 2 * n
x = x + 1 -- watch out!
Это отлично подходит ML или Scheme let *, но у Haskel есть схема letrec семантики, без ограничения на лямбда-значения. Неудивительно, что это сложный материал!
Ответ 7
Подводя итог другим ответам кратко:
- лексический охват
- aliasing так же просто, как
x = 1; y = x
, но обычно не имеет значения, потому что вещи неизменяемы.
Синтаксис let
, который вы используете в вашем примере, выглядит как интерактивный запрос ghci>
. Все в интерактивном режиме происходит внутри монады IO, поэтому все может казаться более изменчивым, чем обычно.
Ответ 8
Ну, как я уже сказал, люди уже сказали, что у Haskell нет переменных, найденных на большинстве других языков, у него есть только выражения. В вашем примере let x = 10
x - это выражение, которое всегда оценивается до 10. Фактически вы не можете изменить значение x позже, хотя вы можете использовать правила определения области видимости, чтобы скрыть его, указав, что x является другим выражением.
Ответ 9
Да, у Haskell есть псевдонимы. Попробуйте эту небольшую программу:
import Data.IORef
main :: IO ()
main = do x <- newIORef 0 -- write 0 into x
readIORef x >>= print -- x contains 0
let y = x
readIORef y >>= print -- y contains 0
writeIORef x 42 -- write 42 into x
readIORef y >>= print -- y contains 42