В DAML, как найти и заменить элемент в списке

Если у меня есть список данных [Элемент], как лучше всего найти и изменить в нем элемент.

aList : [Item]
searchName : Text
newPrice : Decimal


- I can find the element using 
let a : Optional Int = findIndex (\a -> a.name == searchName) aList

-but this doesn't change the value of the List
let (aList !! fromSome a).price = newPrice

data Item = Item 
  with
    name : Text
    price : Decimal
  deriving (Eq, Show)

person Frankie    schedule 22.05.2019    source источник


Ответы (1)


Значения в DAML являются неизменяемыми. Это означает, что после создания списка невозможно обновить какое-либо значение в нем. Однако существует множество вспомогательных функций, которые можно использовать для создания нового списка, очень похожего на старый, но с некоторыми изменениями. В качестве примера:

let newList = map (\a -> if a.name == searchName then a{price = newPrice} else a) aList

Функция map берет каждый элемент списка и применяет заданную функцию. Функция, которую мы передаем, изменяет price для тех, у кого есть правильное имя, и возвращает все остальные без изменений. Обратите внимание, что в отличие от вашей версии, это изменяет все элементы с searchName, а не только первый - я предполагаю, что это нормально (но если нет, посмотрите на такие функции, как partition, чтобы сначала разделить список).

person Neil Mitchell    schedule 22.05.2019
comment
Спасибо, Нил, все работает отлично. Просто любопытно, можно ли это сделать с помощью Map. Не нашел в Map функции, которая может вернуть новую карту обратно... - person Frankie; 23.05.2019
comment
Если вы работаете с типом данных Map, то есть функция fmap, которая работает с любым Functor, а Map является Functor. Просто замените map выше на fmap. - person Neil Mitchell; 23.05.2019