2012-04-01 4 views
13

Oigo que Data.Text va a reemplazar String s en futuras versiones de Haskell. Un problema que tengo con esto es que (++) se define solo para listas. Para concatenar dos Text s, necesito utilizarForma estándar de unir dos Data.Texts sin `mappend`

text1 `mappend` text2 

que obtiene lo más detallada rápidamente. Idealmente, me gustaría poder usar ++ en estos Text s, pero si no, ¿cuál es otra alternativa? Podría definir mi propio operador infijo, pero me gustaría una forma estándar de hacerlo.

Respuesta

17

De GHC 7.4 (no estoy seguro de qué versión de punto) hay un operador predefinido <> que funciona igual que mappend. Por lo que será capaz de decir

text1 <> text2 

Así que eso es el operador "estándar" infija, pero no es disponible en todas partes todavía.

+1

Es un operador mal llamado. '<>' tiene la semántica de "no igual a". Hubiera sido más agradable generalizar '++' para trabajar en todos los Monoids. –

+8

<> fue elegido porque ya estaba siendo utilizado por las bonitas bibliotecas de impresión con semántica monoidal, y es la opción menos molesta que no rompe el código existente, o tiene sesgos impares. Por otro lado, la generalización (++) no se puede hacer de una manera que resulte en buenas bibliotecas de impresión bonitas debido al nivel de precedencia, y solía tener otro significado antes de haskell 98, cuando se usaba para lo que llama a mplus ahora. Si evitáramos cosas con significados en otros idiomas, ¡no tendríamos operadores! Los operadores <<, >>, -,!,%,: Etc. todos tienen otra semántica en otros idiomas también. –

+0

Extraño, estoy tratando de usarlo pero obtengo 'No en el alcance: '<>' '. GHC 7.10.3 – klappvisor

1

Simplemente use mconcat para todo tipo de monoides. No necesita importar nada, y el código se ve mucho más limpio con él.

ejemplo:

{-# LANGUAGE OverloadedStrings #-} 

import   Data.Text 

table :: Text 
table = "user" 

fields :: [Text] 
fields = ["id","nickname","password","date","posts","comments"] 

insertquery :: Text -> [Text] -> Text 
insertquery table fields = mconcat 
    ["insert into ",table," (",names,") values (",vals,");"] 
    where 
    names = insertcomma fields 
    vals = insertcomma [singleton '?' | _ <- fields] 
    insertcomma = intercalate (singleton ',') 

y el resultado se da:

campos de la tabla

λ> insertQuery

"se insertan en el usuario (id, apodo, contraseña, fecha, mensajes, comentarios) valores (?,?,?,?,?,?); "

+0

No estoy seguro de estar de acuerdo en que 'mconcat [...] 'es mejor que' <> ', especialmente cuando hay solo dos o tres valores para combinar. Pero definitivamente es una opción que vale la pena considerar para concatenaciones más grandes como su ejemplo. – leftaroundabout