Предложение Where в функции haskell без параметров

substitute':: (Eq a)=> a -> a -> [a] -> [a]
substitute' x y = map substituteOne
                  where
                    substituteOne x' | x == x'   = y
                                     | otherwise = x'

Итак, смысл этой функции в том, что она принимает два входа типа а и список типа а и заменяет все элементы в списке [а], происходящие из «первого» а, на «второй» а. По крайней мере, так написано в описании задачи.

Я уже реализовал рекурсивную версию, но также нужна функция с предложением where.

Так что это решение для него. Почему-то у меня вопросы:

  1. как replaceOne во второй строке может работать без каких-либо параметров?
  2. где мы даем список в качестве входных данных? или где мы указываем, ЧТО мы делаем с этим списком? Я имею в виду, что компиляция и выполнение работают, но я почему-то этого не вижу.
  3. что такое х'? он никогда нигде не определяется, мы просто начинаем с ним как-то работать (возможно, относится и к вопросу 1)
  4. map нужна функция и список, чтобы она работала. здесь у нас есть функция карты _. относится, может быть, к 2., но что будет на выходе replaceOne x' ?

При необходимости результат выглядит так:

substitute' 5 10 [1, 5, 2, 5, 3, 5]
[1,10,2,10,3,10]
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
93
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

substitute имеет тип a -> a -> [a] -> [a], что означает, что он принимает аргумент один и возвращает функцию типа a -> [a] -> [a]. Это связано с тем, что (->) является правоассоциативным, а приведенный выше тип эквивалентен a -> (a -> [a] -> [a]).

Поскольку приложение функции левоассоциативно, вызов типа substitute x y эквивалентен (substitute x) y; y — это аргумент функции, возвращаемый substitute x.

Когда кто-то пишет

substitute x y = ...

это синтаксический сахар для

substitute = \x -> \y -> ...

Кроме того, поскольку map substituteOne' имеет тип [a] -> [a], это делает его подходящим значением для возврата substitute x y.

substitute1 принимает параметр x'. Биты между символами | и = являются защитными условиями. Поскольку эта конкретная функция имеет только одно условие, вы можете переписать ее следующим образом:

substitute1 x' = if x == x' then y else x'

Поскольку это находится в предложении where, substitute1 также имеет доступ к параметрам x и y основной функции.

Ответ принят как подходящий

(1) how can substituteOne in the second line work without any parameters?
(2) where do we give a list as input? or where do we state what we do with that list? I mean compiling and executing it works, but somehow I don’t see it

Параметры все еще там; это карри на работе. Рассмотрим часть инфиксного оператора(+1), который является частным случаем частичное применение. Получив число, он производит число, которое на единицу больше. Свидетель:

λ> :t (+1)
(+1) :: Num a => a -> a

Мы могли бы определить функцию для увеличения всех элементов списка, назвав список

λ> :t \l -> map (+1) l
\l -> map (+1) l :: Num b => [b] -> [b]

но это оказывается ненужным из-за карри.

λ> :t map (+1)
map (+1) :: Num b => [b] -> [b]

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

(3) what is x'? it is never defined anywhere, we just start working with it somehow (maybe refers also to question 1)

Но вы делать определяете x' как параметр substituteOne!

Рассмотрим тип map:

λ> :t map
map :: (a -> b) -> [a] -> [b]

Его первый аргумент является функцией одного параметра. Чтобы ваша программа выполняла проверку типов, типы должны выстроиться в линию. Мы можем подчеркнуть это для substituteOne, добавив необязательную аннотацию типа, но придется немного потрудиться (включив расширение переменные типа с областью действия), потому что substituteOne — это внутренняя функция со ссылками на внешние сфера,

substitute':: forall a. Eq a => a -> a -> [a] -> [a]
substitute' x y = map substituteOne
                  where
                    substituteOne :: a -> a
                    substituteOne x' | x == x'   = y
                                     | otherwise = x'

(4)map needs a function and a list, so that it works. here we have map function _. refers maybe to 2., but what would be the output of substituteOne x'?

Использование безымянных аргументов в точке приложения, как в вашем коде с map substituteOne, известно как бесточечный стиль. В вашем случае есть две невидимые «точки» или имена переменных: аргумент на substituteOne и аргумент списка на map.

Вы можете быть откровенны обо всем, как в

substitute'' :: Eq a => a -> a -> [a] -> [a]
substitute'' x y l = map (\x' -> if x == x' then y else x') l

но это гораздо более загромождено по сравнению с ним.

Значения, выдаваемые substituteOne, собираются в списке, полученном с map.

Другие вопросы по теме