lomeo: (лямбда)
[personal profile] lomeo
Оказывается, есть и такая вещь в Хаскеле. Существует как расширение системы типов, есть ограничения, пользы большой не вижу, но пусть будет.

При dynamic scoping за связывание переменной отвечает вызывающий код, а не вызываемый.

Пример

function foo()
{
    print x; // x имеет динамическую область видимости.
}

function bar()
{
    var x = 5;
    foo(); // вот здесь x и привяжется.
}



В Haskell dynamic scoping реализуется с помощью Implicit parameters (IP). IP расписываются в Implicit Parameters: Dynamic Scoping with Static Types. Там объясняется как в HM-типизацию внедрить dynamic scoping. А вот как это выглядит практически:

Во первых, не забудем флажок -fimplicit-params, который включает поддержку IP.

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

sortBy :: (a -> a -> Bool) -> [a] -> [a]  

sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]  
sort = sortBy ?cmp


Т.е. в контексте типа мы должны определить все динамически связанные переменные в виде ?name :: type
Но подобные вещи допускаются только в контексте типа функции, поддержки классов и инстансов нет.

Использовать подобную функцию очень просто - переменные связываются с помощью let или where.

let ?cmp = (<) in sort xs


Рекурсивного поиска по умолчанию нет. Для того, чтобы определить, что переменную следует искать выше, надо аннотировать это явно:

least :: (?cmp :: a -> a -> Bool) => [a] -> a
least = head . sort


Есть даже забавный пример по этому поводу:

getLen :: [a] -> Int
getLen xs = let ?acc = 0 in len_acc xs

-- len_acc :: (?acc :: Int) => [a] -> Int
len_acc [] = ?acc
len_acc (x:xs) = let ?acc = ?acc + (1::Int) in len_acc xs


Если мы раскомментируем строку с типом функции len_acc, то getLen "test" будет возвращать 4, иначе 0.

Конечно, использовать это я буду вряд ли, но читать было интересно. Тема легкая и нескучная, имхо.

Date: 2006-10-30 11:29 am (UTC)
From: [identity profile] thesz.livejournal.com
Я почитал про это дело в ghc user guide. Говорят, поведение программ меняется от добавления объявлений типов и теряется возможность рассуждения о программах вне контекста.

Поэтому я решил воздержаться от использования этой штуки.

Date: 2006-10-30 11:45 am (UTC)
From: [identity profile] lomeo.livejournal.com
В статье, о которой я упоминул рассматривается связь java+haskell, через JNI. Дело в том, что в JNI (если ты не писал) первым параметром в функциях всегда выступает jni environment, из которого мы можем тянуть нужные нам классы, объекты и т.д. В Ява коде его нет, разумеется, но неявно он присутствует. Так вот в Хаскеле можно сделать точно так как в Ява, как бы подразумевая, что энвайронмент есть всегда. В этом смысле очень удобно, другое дело, что такие задачи все таки редкость.

Date: 2006-10-30 11:39 am (UTC)
From: [identity profile] -darkus-.livejournal.com
Если честно, то на первый взгляд кажется какой-то хернёй. Не знаю, зачем это ввели в Хаскел. Кажется, что будто бы нерадивому студенту, который не знал, как подобные вещи сделать без DS, приспичило вставить эту возможность. И вставили ради такого нерадивого студента.

Она нефункциональна.

Date: 2006-10-30 12:26 pm (UTC)
From: [identity profile] lomeo.livejournal.com
Не понял, как сделать подобную вещь без DS?

Тут проблема в другом - то, как это реализовано в Хаскель - это не то, что требуется (мне требовалось при работе с Лиспом) от DS. Так, например, есть баг, не позволяющий определять контекст типа лексической переменной, если такой же тип не используется в типе функции. Т.е. (Show a, ?x :: a) => Int -> Int писать нельзя, а (Show a, ?x :: a) => a -> Int, или (?x :: a) => Int -> Int можно. Во вторых, нельзя использовать функции типа ((?x :: a) -> a) -> a, т.е. ФВП, использующая функцию с лексическими переменными. А без этого DS лишается практической силы. Но само DS от этого не теряет своих преимуществ.

Date: 2006-10-30 11:48 am (UTC)
From: [identity profile] migmit.livejournal.com
Кашшмар.

Date: 2006-10-30 12:27 pm (UTC)
From: [identity profile] lomeo.livejournal.com
Да, я такоооой! :-)

Date: 2006-12-08 09:38 pm (UTC)
From: [identity profile] kurilka.livejournal.com
А чего это у тебя динамическое связывание и лексическое это одно и то же?
См. Википедию (http://en.wikipedia.org/wiki/Scope_(programming)) хотябы. Лексическое - это синоним статического, т.е. противоположного динамическому, связывания.

Date: 2006-12-09 09:23 am (UTC)
From: [identity profile] lomeo.livejournal.com
Путаюсь в терминах, спасибо, поправил.

Date: 2006-12-09 09:25 am (UTC)
From: [identity profile] kurilka.livejournal.com
Да не вопрос, местами есть где попутаться :)

Profile

lomeo: (Default)
Dmitry Antonyuk

April 2024

S M T W T F S
 123456
7891011 1213
14151617181920
21222324252627
282930    

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 5th, 2025 02:48 pm
Powered by Dreamwidth Studios