2012-04-01 14 views
13

Słyszałem, że Data.Text ma zastąpić String s w przyszłych wersjach Haskella. Mam jeden problem z tym, że (++) jest zdefiniowany tylko dla list. Aby złączyć dwa Text s, muszę korzystaćStandardowy sposób łączenia dwóch tekstów Data.Text bez `mappend`

text1 `mappend` text2 

który dostaje VERBOSE szybko. Idealnie chciałbym móc użyć ++ na tych s, ale jeśli nie, jaka jest inna alternatywa? Mógłbym zdefiniować własnego operatora infiksów, ale chciałbym to zrobić w standardowy sposób.

Odpowiedz

17

Z GHC 7.4 (nie wiem, która wersja punktu) istnieje predefiniowany operator <>, który działa tak samo, jak mappend. Więc można powiedzieć

text1 <> text2 

tak, że to „standard” operator infix, ale to nie jest jeszcze dostępna wszędzie.

+1

To jest kiepsko nazwany operator. '<>' ma semantykę "nie równa się". Byłoby przyjemniej uogólniać '++', aby działało na wszystkich Monoidach. –

+8

<> został wybrany, ponieważ był już używany przez ładne biblioteki drukarskie z semantyką monoidalną, i jest to najmniej natarczywa opcja, która nie łamie istniejącego kodu lub ma dziwne błędy. Generalizowanie (++) z drugiej strony, nie może być wykonane w sposób, który sprawia, że ​​ładne ładne biblioteki drukowania ze względu na poziom pierwszeństwa, i miał jeszcze inne znaczenie przed haskell 98, kiedy był używany do tego, co mamy zadzwoń teraz do mplus. Gdybyśmy unikali rzeczy o znaczeniach w innych językach, nie mielibyśmy operatorów! Operatory <<, >>, -,!,%,: Itp. Mają również inne semantyki w innych językach. –

+0

Dziwne, próbuję go użyć, ale otrzymuję komunikat "Not in scope:" <> ''. GHC 7.10.3 – klappvisor

1

Po prostu użyj mconcat dla wszystkich typów monoidów. Nie musisz importować niczego, a kod wygląda znacznie czystszy.

przykład:

{-# 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 ',') 

a wynik daje:

λ> insertquery pola tabeli

„wstawić do użytkownika (id, nick, hasło, data, wpisy, komentarze) wartości (?,?,?,?,?,?); "

+0

Nie jestem pewien, czy zgadzam się 'mconcat [...]' jest lepszy niż '<>', szczególnie gdy są tylko dwie lub trzy wartości do połączenia. Ale zdecydowanie jest to opcja warta rozważenia w przypadku większych konkatenacji, jak na przykład. – leftaroundabout

Powiązane problemy