LINUX.ORG.RU

[Haskell] списки

 


0

1

Хочу написать функцию, которая бы возвратила все n-значные числа (можно в виде списка цифр), который состоят из нечётных цифр и соседние цифры отличаются на два.

Пока я написал так

-- первая цифра
let ds=[1,3,5,7,9]
-- следующая цифра
let nexts 1 = [3]; nexts 9 = [7]; nexts n = [n-2,n+2]

-- список вохможных 5-значных чисел
let as = [[a,b,c,d,e]|a<-ds,b<-nexts a, c<-nexts b,d<-nexts c,e<- nexts d]
Но я хочу, чтобы можно было удобно вызывать функцию, напр. f ds 3 — список всех 3-хзначных чисел, удовлетворяющих условию.

Наверное как-то через монады можно. Я совсем ещё новичок и был бы признателен за красивое решение.



Последнее исправление: toady2 (всего исправлений: 1)

Вот, например:

myXs :: [Int] -> Bool
myXs x = all odd x && all ((== 2) . abs) (zipWith (-) x $ tail x)

nDigits :: Int -> [[Int]]
nDigits 0 = [[]]
nDigits n = concatMap (\x -> map (: x) [0..9]) $ nDigits (n - 1)

f :: ([Int] -> Bool) -> Int -> [[Int]]
f g n = filter g $ nDigits n

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

А можно как-нибудь без фильтрования (это скучно ;) ибо в лоб).

Вообще, как сделать функцию, которая сделает что-то типа

[[a,b,c,d,e]|a<-ds,b<-nexts a, c<-nexts b,d<-nexts c,e<- nexts d]
только кол-во элементов в списке я сам устанавливаю (f 5)? Я пробовал мудить с do-блоками, но ничего не вышло, ибо пока ещё там мало понимаю.

------------

Предположим, требуется найти не сами числа, а их кол-во. Тогда можно сделать так:

-- кол-во 5-значных чисел
length $ ds >>= nexts >>= nexts >>= nexts >>= nexts
-- 42
Но и тут та же проблема: как не вручную 5 раз nexts писать, а сделать функцию f n (тогда f 5 = 42)?

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

Ну и зачем плодить сущности? Скучно, видите ли. concatMap, между прочим, для списков идентичен (=<<). По делу: чтобы применить функцию n раз, используется iterate :: (a -> a) -> a -> [a]. Аргументами являются начальное значение x и функция f, на выходе — список [x, f x, f (f x) ...]. Тогда

f :: Int -> [[Int]]
f n = iterate (>>= nexts) ds !! (n - 1)

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

А как iterate прикрутить к [[a,b,c,d,e]|a<-ds,b<-nexts a, c<-nexts b,d<-nexts c,e<- nexts d] ?

Ну и зачем плодить сущности? Скучно, видите ли. concatMap, между прочим, для списков идентичен (=<<).


Меня сий вопрос только ради академического интереса волнует. Хочется вжиться в монады, пока они я тяжело даются. Крутая learning curve в этом месте ;)

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

А как iterate прикрутить к [[a,b,c,d,e]|a<-ds,b<-nexts a, c<-nexts b,d<-nexts c,e<- nexts d] ?

Да никак, пожалуй. Сейчас там кол-во цифр жёстко зашито, а если менять на общую функцию, то получится аналог [x | x <- f y], что эквивалентно f y. Короче, профита от данной конструкции здесь я не вижу.

exlevan
()

ЗЫ: Хаскель ты методом научного тыка не поймешь (это тебе не лисп).

Кури дискретку, абстрактную алгебру, матлогику и теорию типов.

А монады всякие — это штука крайне простая, в этому-то и вся сложность %)

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

Хочется вжиться в монады, пока они я тяжело даются. Крутая learning curve в этом месте ;)

Typeclassopedia прочитай. Там про монады и другие классы типов обстоятельно и по порядку написано, must read короче.

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

>матлогику, дискретку
Суть одно и то же, причем оное нужно знать всем разработчикам, а не только штангистам.

абстрактную алгебру

Нахрена?

теорию типов

Зачем?
Даже для хаскеля это лишнее.

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

ЗЫ: Хаскель ты методом научного тыка не поймешь (это тебе не лисп).

Если это так, то на хаскеле невозможно было бы писать что-то практическое.

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

>Суть одно и то же

Ну путай. Это совсем не одно и то же. Булева алгебра — вещь достаточно конкретная. И с мат. логикой имеет мало общего, в лучшем случае как достаточно специфичный частный случай.

Нахрена?


Потому что в дискретную математику обычно пихают всякую хрень. И теория групп, например, детально рассматривается именно там.

Даже для хаскеля это лишнее.


Для хаскеля теория категорий — лишнее. А вот теория типов — совсем нет.

а не только штангистам


Не нужно форсить унылые мемы, ок?

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

>Если это так, то на хаскеле невозможно было бы писать что-то практическое.

Почему ты так думаешь?

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

> Если это так, то на хаскеле невозможно было бы писать что-то практическое.

именно поэтому, писать на нём что-либо практическое невозможно! )))

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

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

Благо каскель достаточно прагматичен, что бы на нем писали не только штангисты.

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

> в дискретную математику обычно пихают всякую хрень. И теория групп, например, детально рассматривается именно там.

Это в каком заборостроительном вузе?

anonymous
()

У чём проблема? Рекурсию не умеем?

nSteps 1 step initial = [[initial]]
nSteps n step initial = [initial:xs | a <- step initial, xs <- nSteps (n-1) step a]
f n step initials = [digits | initial <- initials, digits <- nSteps n step initial]
Другой вопрос, что явно использовать рекурсию - не есть признак профессионализма, но вопрос о том, как без неё прожить, я оставлю на потом.

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