Skip to content

Instantly share code, notes, and snippets.

@snoyberg
Created January 13, 2011 22:03
Show Gist options
  • Save snoyberg/778712 to your computer and use it in GitHub Desktop.
Save snoyberg/778712 to your computer and use it in GitHub Desktop.
Possible approach to internationalization in Haskell
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE FlexibleContexts #-}
import Data.Maybe (fromMaybe)
class MaybeRead a where
maybeRead :: String -> Maybe a
class MaybeRead (Language a) => I18N a where
type Language a
type Message a
i18n :: Language a -> a -> Maybe (Message a)
i18nDefault :: a -> Message a
i18nLang :: I18N a => String -> a -> Message a
i18nLang lang a = fromMaybe (i18nDefault a) $ maybeRead lang >>= flip i18n a
i18nLangs :: I18N a => [String] -> a -> Message a
i18nLangs [] a = i18nDefault a
i18nLangs (l:ls) a =
case maybeRead l >>= flip i18n a of
Nothing -> i18nLangs ls a
Just m -> m
data Result =
Correct
| TooLow Int
| TooHigh Int
| NotANumber String
data Lang = English | Hebrew | French
instance MaybeRead Lang where
maybeRead "en" = Just English
maybeRead "en-us" = Just English
maybeRead "he" = Just Hebrew
maybeRead "he-il" = Just Hebrew
maybeRead _ = Nothing
instance I18N Result where
type Language Result = Lang
type Message Result = String -- could be Text, Html, etc
i18n English x = Just $ i18nDefault x
i18n Hebrew Correct = Just "נכון"
i18n Hebrew (TooLow x) = Just $ "קטן מדי: " ++ show x
i18n Hebrew (TooHigh x) = Just $ "גדול מדי: " ++ show x
i18n Hebrew (NotANumber x) = Just $ "נא לתת מספר: " ++ x
i18n French _ = Nothing -- I need to learn French
i18nDefault Correct = "Correct"
i18nDefault (TooLow x) = "Too small: " ++ show x
i18nDefault (TooHigh x) = "Too big: " ++ show x
i18nDefault (NotANumber x) = "Please enter a number: " ++ x
main = do
putStrLn $ i18nLang "en" (TooLow 8)
putStrLn $ i18nLang "es" (TooLow 8)
putStrLn $ i18nLang "he-il" (TooLow 8)
putStrLn $ i18nLang "en" Correct
putStrLn $ i18nLang "en-us" Correct
putStrLn $ i18nLangs ["fr", "de", "en-us", "he"] $ TooHigh 9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment