在 Haskell 中从 Char 映射到 String

map from Char to String in Haskell

我正在尝试弄清楚如何 improve the transliteration 从德语变音符号到 ASCII 以获取 Pandoc 中的 id 标识符。目前只有映射Char -> Maybe Char,将ä转换为a,将ß转换为Nothing等,但最常见的约定映射ä 变成 aeß 变成 ss 等等。这是我目前所拥有的:

import Data.Char (isAscii)
import qualified Data.Map as M

asciiMap' :: M.Map Char String
asciiMap' = M.fromList
  [('6',"Ae")
  ,('4',"Oe")
  ,('0',"Ue")
  ,('3',"ss")
  ,('8',"ae")
  ,('6',"oe")
  ,('2',"ue")
  ]

toAsciiStr :: Char -> String
toAsciiStr c | isAscii c = [c]
             | otherwise = M.findWithDefault "" c asciiMap'

myTranslit :: String -> String
myTranslit [] = []
myTranslit (x:xs) = toAsciiStr x ++ myTranslit xs

我的问题是关于 myTranslit.

是否已经有内置的 map 类函数 someMap :: (a -> [a]) -> [a] -> [a]

是的,您正在寻找的是 concatMap :: Foldable t => (a -> [b]) -> t a -> [b],它将映射后的输出连接起来。由于 []Foldable,因此它可以 专门化 concatMap :: (a -> [b]) -> [a] -> [b] 中,并且进一步(使用 a ~ Charb ~ Char ) 变成 concatMap :: (Char -> [Char]) -> [Char] -> [Char]。请注意,Stringtype String = [Char] 的别名,因此,String 只不过是 Char 演员的列表。

因此您可以使用:

myTranslit :: String -> String
myTranslit = <b>concatMap</b> toAsciiStr

你可以让整个事情像

一样简洁
myTranslit :: String -> String
myTranslit = concatMap $ \c -> case c of
  'Ä' -> "Ae"
  'Ö' -> "Oe"
  'Ü' -> "Ue"
  'ä' -> "ae"
  'ö' -> "oe"
  'ü' -> "ue"
  'ß' -> "ss"
  _ | isAscii c  = [c]
    | otherwise  = ""