Список и оператор cons (:)
очень распространены в Haskell. Минусы - наш друг. Но иногда я хочу добавить в конец списка.
xs `append` x = xs ++ [x]
Это, к сожалению, не является эффективным способом его реализации.
Я написал Треугольник Pascal в Haskell, но мне пришлось использовать :
ptri = [1] : mkptri ptri
mkptri (row:rows) = newRow : mkptri rows
where newRow = zipWith (+) row (0:row) ++ [1]
imho, это прекрасный читаемый треугольник Паскаля и все, но анти-идиома раздражает меня. Может ли кто-нибудь объяснить мне (и, в идеале, указать мне хороший учебник) о том, какова структура идиоматических данных для случаев, когда вы хотите эффективно добавить к концу? Я надеюсь на близкую к списку красоту в этой структуре данных и ее методах. Или, попеременно, объясните мне, почему эта анти-идиома на самом деле не так уж плоха для этого случая (если вы считаете, что это так).
[править] Ответ, который мне больше всего нравится, Data.Sequence
, который действительно имеет "близорукую красоту". Не уверен, как я отношусь к необходимой строгости операций. Дальнейшие предложения и разные идеи всегда приветствуются.
import Data.Sequence ((|>), (<|), zipWith, singleton)
import Prelude hiding (zipWith)
ptri = singleton 1 : mkptri ptri
mkptri (seq:seqs) = newRow : mkptri seqs
where newRow = zipWith (+) seq (0 <| seq) |> 1
Теперь нам просто нужно, чтобы List был классом, так что другие структуры могут использовать его методы, такие как zipWith
, не скрывая его от Prelude или не определяя его.: P