Передать вывод из функции как ввод в другую функцию в Haskell

88
9

Как можно передать вывод из функции как вход в другую функцию.

Например, у меня есть эти две функции

collatz :: (Integral a) => a -> [a]
collatz 1 = [1]
collatz n
|even n = n:collatz (n 'div' 2)
|odd n = n:collatz (n*3 + 1)

И моя другая функция

length' [] = 0
length' (x:xs) = 1 + length' xs

Я хочу вычислить длину списка, который был выведен из моей функции collatz.

наконец, я хочу полностью рассчитать это

numLongChains :: Int  
numLongChains = length (filter isLong (map collatz [1..100]))
where isLong xs = length xs > 15

Но шаг за шагом.

спросил(а) 2021-01-25T15:49:02+03:00 4 месяца, 3 недели назад
1
Решение
100

Вы говорите о функции композиции:

-- assuming signature length' :: [a] -> Int   
composed :: (Integral a) => a -> Int
composed = length' . collatz

Я не уверен, что вы подразумеваете под "шаг за шагом", но для вашего второго вопроса это будет:

numLongChains :: (Integral a) => [a] -> Int
numLongChains = length' . (filter isLong) . (map collatz)
where isLong xs = length' xs > 15

Я сделал это унарной функцией, чтобы она могла работать с любым списком, а не только с [1..100].

ответил(а) 2021-01-25T15:49:02+03:00 4 месяца, 3 недели назад
77

length' последовательности collatz для n равна \n → length' (collatz n). Этот шаблон настолько распространен, что мы дали ему имя: f. g = \x → f (gx) f. g = \x → f (gx). Мы называем это "состав функции". Заменив f, g и x выше на length', collatz и n, мы получим length'. collatz = \n → length' (collatz n) length'. collatz = \n → length' (collatz n). Так:

collatzLength = length' . collatz

Кроме того, вместо того, чтобы писать isLong как вы, мы также можем использовать здесь композицию функций, хотя и немного менее очевидным образом:

isLong xs = length' xs > 15
isLong = \xs -> length' xs > 15
isLong = \xs -> (>) (length' xs) 15
isLong = \xs -> (> 15) (length' xs) -- this is the less obvious bit
isLong = (> 15) . length'

Таким образом, вопрос "является ли последовательность Коллатца для числа n длиннее 15?" теперь можно записать как:

isLongSequence = isLong . collatz

Таким образом, длинные последовательности для чисел [1..100]

filter isLongSequence [1..100]

или с

longSequences = filter isLongSequence

его

longSequences [1..100]

Теперь мы можем написать numLongChains как

numLongChains = length' . longSequences

Число длинных цепочек - это количество (длина) длинных последовательностей.

Теперь, чтобы показать, что это эквивалентно вашему определению, вам нужно знать правило (теорему) о карте и фильтре:

filter p . map f = filter (p . f)

Так

\xs -> filter isLong (map collatz xs)

такой же как

filter isLong . map collatz

такой же как

filter (isLong . collatz)

такой же как

filter isLongSequence

такой же как

longSequences

ответил(а) 2021-01-25T15:49:02+03:00 4 месяца, 3 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема