Idiomatic eficiente Haskell agregar?

List y el operador contras(:) son muy comunes en Haskell. Contras es nuestro amigo. Pero a veces quiero agregar al final de una lista en su lugar.

xs `append` x = xs ++ [x]

Esto, lamentablemente, esn una forma eficiente de implementarlo.

Escribí Triángulo de Pascal en Haskell, pero tuve que usar la++ [x] anti-idioma:

ptri = [1] : mkptri ptri
mkptri (row:rows) = newRow : mkptri rows
    where newRow = zipWith (+) row (0:row) ++ [1]

imho, este es un triángulo de Pascal legible y encantador, pero el anti-idioma me molesta. ¿Puede alguien explicarme (e, idealmente, señalarme un buen tutorial) sobre cuál es la estructura de datos idiomática para los casos en los que desea agregar al final de manera eficiente? Espero una belleza casi similar a una lista en esta estructura de datos y sus métodos. O, alternativamente, explícame por qué este anti-idioma no es tan malo para este caso (si crees que es así).

[editar] La respuesta que más me gusta esData.Sequence, que de hecho tiene una "belleza similar a una lista". No estoy seguro de cómo me siento acerca de la rigurosidad requerida de las operaciones. Más sugerencias y diferentes ideas son siempre bienvenidas.

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

Ahora solo necesitamos que List sea una clase, para que otras estructuras puedan usar sus métodos comozipWith sin ocultarlo de Prelude, ni calificarlo. :PAG

Respuestas a la pregunta(12)

Su respuesta a la pregunta