LINUX.ORG.RU

Хаскель - несколько определений одной функции - порядок применения

 , ,


0

3

Вот программка на Хаскеле

sayMe :: (Integral a) => a -> String

sayMe x
    | x <= 2 = "Less then three!"

sayMe 1 = "One!"

main = putStrLn (sayMe 1)
-- результат  зависит от порядка определений
Здесь печатает «Less then three». Если поменять определения местами, то напечатается «One!». В явном виде я нигде не прочитал, но похоже, что определения обрабатываются по порядку, и первое подходящее применяется.

Эта штука мне нравится, поскольку по сути это тот «полиморфизм», который гениально прост и при этом не налагает никаких требований на систему типов. В С++ или в CLOS методы выбираются не по порядку определения, а по отношению «предок-потомок», или, иными словами «тип-подтип». Это отношение не всегда легко определить.

Но у меня вопросы:

1. Могу ли я размазать определение sayMe по нескольким модулям, ничего не знающим друг про друга?

2. Если да, то как при этом выстраивается порядок определений? Ведь обычно при сборке мы не точно знаем порядок впихивания модулей в готовый исполняемый файл.

3. Есть ли способ воткнуть своё определение перед первым определением, задав свой частный случай?

★★★★★

Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Наиболее существенно для меня (уже вне рамок этого вопроса) вот это:

C++ and Java attach identifying information (such as a VTable) to the runtime representation of an object. In Haskell, such information is attached logically instead of physically to values, through the type system.

Т.е. можно «создавать методы для произвольных типов», если я правильно это понял. Это хорошо, спасибо. Хорошо, что ооп из плюсов разобрали на атомы, но принципиально новых идей я всё же пока не вижу.

den73 ★★★★★
() автор топика
Ответ на: комментарий от utf8nowhere

Годнота! Спасибо! Потом почитаю, сейчас немного некогда стало.

den73 ★★★★★
() автор топика
Ответ на: комментарий от Virtuos86

Нет. Чтобы не было неопределенности. А так - как хош.

anonymous
()
Ответ на: комментарий от den73

А в случае, когда просто перебираем N вариантов без всяких рекурсий и за фиксированное время получаем результат, мы не выходим на такую проблему. Так что зависимость от порядка правил и вообще примитивизм языка описания - не всегда минус

Чего чего? Мы видимо говорим о разных вещах. Линейный проход всегда хуже параллельного. Если сможешь доказать обратное на практике, сниму шляпу.

Т.е. надо составить программу, которая завешает Curry http://www-ps.informatik.uni-kiel.de/smap/smap.cgi?new/curry но не завешает Haskell http://www-ps.informatik.uni-kiel.de/smap/smap.cgi?new/haskell

anonymous
()
Ответ на: комментарий от anonymous

В том, что там в втором разделе говорится про lifted types, которые имеют прямое отношение к ошибкам в рантайме? Да, ты безграмотен, учись старательнее.

GoodRiddance
()
Ответ на: комментарий от GoodRiddance

В том, что там в втором разделе говорится про lifted types, которые имеют прямое отношение к ошибкам в рантайме? Да, ты безграмотен, учись старательнее.

Но в идрисе то ты так не сделаешь :)

anonymous
()
Ответ на: комментарий от anonymous

Линейный проход всегда хуже параллельного.

Это идеологизированное, чрезмерно обобщённое высказывание. Его опровергнуть - проще простого: «за двумя зайцами погонишься - ни одного не поймаешь».

den73 ★★★★★
() автор топика
Ответ на: комментарий от GoodRiddance

В том, что там в втором разделе говорится про lifted types, которые имеют прямое отношение к ошибкам в рантайме?

Не имеют. Пи-тип через lifted не моделируется.

anonymous
()
Ответ на: комментарий от den73

Наиболее существенно для меня (уже вне рамок этого вопроса) вот это:

Там не совсем правильно написано. В хаскеле точно так же есть передается в метод тайпкласса дополнительный аргумент, содержащий аналог vtable, через этот механизм работает high-rank полиморфизм.

anonymous
()
Ответ на: комментарий от anonymous

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

qnikst ★★★★★
()
Ответ на: комментарий от qnikst

Вот в RankNType уже без передачи словаря никак.

Об этом и речь. В случае high-rank это уже не деталь реализации, а необходимость.

anonymous
()
Ответ на: комментарий от qnikst

Я так понял Вы разбираетесь. Я уже знаю, что

fun :: Some a => a -> ...
fun arg = ...
превращается в
fun :: Some_dict -> a -> ...
fun d arg = ...
и может специализироваться.

Что происходит с

fun :: Some f => f a -> ...
fun arg = ...
и почему не может специализироваться?

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.