Список и оператор минусов (:)
очень распространены в Haskell.Минусы это наш друг.Но иногда я хочу добавить в конец списка.
xs `append` x = xs ++ [x]
К сожалению, это не эффективный способ его реализации.
Я написалup Треугольник Паскаля в Хаскеле, но мне пришлось использовать ++ [x]
анти-идиому:
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