LINUX.ORG.RU

Помогите пройти тест по Haskell

 ,


1

2
Отметьте функции, которые не могут привести к расходимости ни на каком корректном наборе аргументов.

foo a = a

bar = const foo

baz x = const True

quux = let x = x in x

corge = 10

grault x 0 = x
grault x y = x

garply = grault 'q'

waldo = foo

Я нашел, только baz и corge. Но это не правильный ответ.

Ответ на: комментарий от Miguel

Я сказал, что в разумном (насколько это возможно) инстансе для Int->Int будет сходящаяся функция, в общем «поясняющий пример» крайне неудачно подобран, я к этому, лучше было бы без него совсем.

Если уж приводить пример расходящегося fromInteger то нужно не мудурствуя лукаво показывать пример const undefined :).

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

Да, тут вообще не может быть никаких вопросов. Более того, я скажу что терм с типом `а` является функцией и вот тут уже вопросы возникнуть могут.

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

Ещё раз, для особо одарённых. Не сама fromInteger может расходиться, а её результат. Не const undefined, а, например, const (floor . sqrt).

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

ЧТО ЗА ИДИОТИЗМ ТЫ ПИШЕШЬ?

Не сама fromInteger может расходиться, а её результат.

ОТКУДА ТЫ ЭТО ВЗЯЛ?!

Одарённый, блин...

Чем `const undefined` отличается от `const (floor . sqrt)` с точки зрения расходимости?

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

С для тех, кто по какой-то причине (наверное т.к. давно познакомился), считает, что может учить других Haskell

instance Num (Int -> Int) where
   fromInteger = const (floor . sqrt . fromIntegral) 

тогда corge - сходящаяся фукнция, которая радостно возвращает функцию, которая может расходиться при некоторых аргументах. Тут уже вопрос к автору, как это трактовать.

Если fromInteger будет для данного типа расходиться, то corge - расходится без вопросов.

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

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

Более того, я скажу что терм с типом `а` является функцией и вот тут уже вопросы возникнуть могут.

С каких пор? Как давно, например, Int и Char стали функциями?

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

С каких пор?

С тех, когда задашь подходящую аксиоматику. Как я сказал, тут уже возникают вопросы. Но мне кажется, что мы не об этом случае говорили, не так ли? Или вопросов про Num a => a больше нету?

Предположим, что нету и перейдём к a.

1. Кто тебе разрешил специализировать a до Int и Char?

2. Даже если разрешили, то и Int и Char - отличные функции из $$\empty$$ в Int и Char соответственно. Такие «тривиальные функции» не особно интересны, но если вспомнить, что это Lifted значения и существует ленивость это имеет смысл.

3. Так же интересующиеся могут заметить, что они совпадают (() -> Int) с точностью до изоморфизма.

Более интересный вопрос является ли терм с кайндом `#` функцией. Но ответ на этот вопрос я тебе предлагаю написать самостоятельно.

qnikst ★★★★★
()

Какой же он сложный...

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

Или вопросов про Num a => a больше нету?

Это ты решил сделать более сильное утверждение, перейдя от Num a => a к просто a:

Более того, я скажу что терм с типом `а` является функцией и вот тут уже вопросы возникнуть могут.

Если с Num a => a ещё как-то можно попробовать отбрехаться передачей инстанса в core(что будет выглядеть унылыми понтами, кстати), то с просто a утверждение сомнительно вдвойне.

1. Кто тебе разрешил специализировать a до Int и Char?

Неявный forall же.

Даже если разрешили, то и Int и Char - отличные функции из $$\empty$$ в Int и Char соответственно. Такие «тривиальные функции» не особно интересны, но если вспомнить, что это Lifted значения и существует ленивость это имеет смысл.

Вот сваливать невычисленные танки в 0-арные функции — это уже слишком. Я могу понять такое в контексте, например, схемы, где ленивость закатывается вручную пустыми замыканиями. Но там чётко разделено, где отложенное вычисление, а где нет. Здесь же... ну вот как может язык повернуться назвать сконструированный конструктором данных объект 0-арной функцией? Ну чушь же, ну.

Кстати, если посмотришь удалённые коментарии, то я сперва написал про то, что арность функции corge не определена (а не про то, что не определено, является ли corge вообще функцией), но потом этот комент удалил из-за неграмотной формулировки.

Так же интересующиеся могут заметить, что они совпадают (() -> Int) с точностью до изоморфизма.

Нет, конечно же, не совпадают. Потому что у типа () два значения, а не одно.

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

Если с Num a => a ещё как-то можно попробовать отбрехаться передачей инстанса в core(что будет выглядеть унылыми понтами, кстати),

Нет, не понты, и ты знаешь почему.

Кстати, если посмотришь удалённые коментарии, то я сперва написал про то, что арность функции corge не определена (а не про то, что не определено, является ли corge вообще функцией), но потом этот комент удалил из-за неграмотной формулировки.

С арностью вообще все плохо, и это нужно спрашивать у автора что он имеет ввиду, т.к. если ты «попросишь» corge вернуть Int -> Int, то corge вернёт тебе такую отличную функцию/значение, и этот вызов сходится. А что ты передаешь в это значение дальше это уже твои личные проблемы, которые никого не волнуют.

Позволю себе напомнить изначальное утверждение:

является ли corge функцией или нет, не говоря уже про сходимость/расходимость

независимо от споров о том, что является функцией и нет (зависящее от аксиоматики), «не говоря уже» никогда не будет правильным. Т.к. независимо от того, чем ты назовешь выражение, оно может быть сходящимся и расходящимся, например

three :: Int
three = error "three"

это ж не функция?

И это тоже не функция:

manyone :: Int
manyone = 1+manyone

Нет, конечно же, не совпадают. Потому что у типа () два значения, а не одно.

я должен был там дописать с TK точки зрения, каюсь, я думал написал. Там у Unit одно значение.

P.S. на самом деле самое разумное определение с денотационной точки зрения будет, наверное, что функция это * -> *. Но я не вижу причин выбираеть её в случайном споре на лоре.

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

доходит дело до вычисления из за сравнения с нулём.

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

нет, у тебя неполное определение grault. Там в оригинале есть сопоставление с образцом, обрати внимание. Из за этого будет расходимость.

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

не понимаю разницы между 10 и строкой. пойду перечитаю тред

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

Ты издеваешься что ли? Там из-за ленивости второй аргумент вообще считаться не будет, потому что первый задали. С образком 0 он не совпадает, это было очевидно, поэтому не показывал, ну пожалуйста, держи «полное определение grault»:

Prelude> let grault x 0 = x
Prelude> let grault x y = x
Prelude> let garply = grault 'q'
Prelude> garply undefined
'q'
Psych218 ★★★★★
()
Ответ на: комментарий от Psych218

Этот grault можно было с тем же успехом задать как grault x _ = x, а garply вообще плевать на аргумент, он не будет считаться, эта функция просто возвращает 'q'. Её можно задать как garply _ = 'q'

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

А если не в ghci проверять, а, например, из модуля загружать, то будет undefined...

Разве? Может быть. А почему так? Разве оно не компилится так, что garply просто возвращает 'q' всегда?

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

в ghci не получится определить так функцию. создай файл, напиши там, потом загрузи файл.

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

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

да, let в ghci просто переопределяет текущее значение, похоже. я не знаю как в ghci задать аналогично тому что задаётся в файле.

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

В курсе говорили про такую конструкцию.

trupanka
() автор топика
Ответ на: комментарий от AndreyKl

Хе-хе, `в haskell report заглянул`. Отличная шутка. Еще даже до монад не дошло дело. С трудом и божьей помощью списки удалось кое-как усвоить. Это очень сложный язык для меня... уже дважды хотелось вообще бросить его изучать.

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

В курсе говорили про такую конструкцию.

Я что-то видимо пропустил это.

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

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

кстати монады да, довольно сложны в понимании, когда речь идёт не о монадах вообще, а о конкретно ридере/райтере/стейт и их глубоком понимании.

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

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

qnikst

Позволю себе напомнить изначальное утверждение:

является ли corge функцией или нет, не говоря уже про сходимость/расходимость

независимо от споров о том, что является функцией и нет (зависящее от аксиоматики), «не говоря уже» никогда не будет правильным. Т.к. независимо от того, чем ты назовешь выражение, оно может быть сходящимся и расходящимся, например

three :: Int
three = error "three"

это ж не функция?

И это тоже не функция:

manyone :: Int
manyone = 1+manyone

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

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

Должно окупиться эффективностью, по идее

Скажи это моему quick-сорту, который работает 10 сек. на 1000 элементах. lol

приходится мыслить в незнакомых категориях

Угу, рекурсивные алгоритмы на списках тяжело даются. К такому курсу не помешало бы прикладывать какую-нибудь методичку по динамическому программированию, ну или какую-нибудь книжку, которая разбирала бы такие алгоритмы. А так... получается quick-sort в стиле `C`.

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

Скажи это моему quick-сорту, который работает 10 сек. на 1000 элементах. lol

Эфективностью в первую очередь в смысле сочетания скорости написания и качества написанного кода.

Эффективность времени исполнения (безотносительно твоего личного квик-сорта, кстати, как ты это сделал?) отдельностоящая проблема, на сколько я это себе представляю, которая, кажется, уже на более-менее приемлемом уровне.

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

ващет в graul было 2 выражения с паттерн-матчингом в первом, почему ты изменил условие?

qnikst ★★★★★
()
Ответ на: комментарий от Psych218
> :{
> let grault x 0 = x
      grault x y = x
  let graply = grault 'q'
> :}
qnikst ★★★★★
()
Ответ на: комментарий от AndreyKl

получится, нужно использова :{ и :} ну или явный case

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

Скажи это моему quick-сорту, который работает 10 сек. на 1000 элементах. lol

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

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

у меня квиксорт вот такой

qsort :: Ord a => [a] -> [a]
qsort [] = []
qsort [x] = [x]
qsort (x:xs) = qsort (filter (< x) xs) ++ x : qsort (filter (>= x) xs)


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

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

в этом курсе честный квиксорт на самом деле не требуется.

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

есть такая функция Data.List.partition

спасибо, похуглил, то что нужно.

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