Advertisement
Guest User

Untitled

a guest
Jul 17th, 2019
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.07 KB | None | 0 0
  1. {-# OPTIONS_GHC -Wall #-}
  2. {-# LANGUAGE FlexibleInstances #-}
  3. {-# LANGUAGE GADTs #-}
  4. {-# LANGUAGE RoleAnnotations #-}
  5.  
  6. module List (List, fromText, list, unList) where
  7.  
  8. import qualified Data.Text as T
  9.  
  10. type role List nominal
  11. data List a where
  12. Nil :: List a
  13. Cons :: a -> List a -> List a
  14. IsText :: T.Text -> List Char
  15.  
  16. instance Functor List where
  17. fmap _ Nil = Nil
  18. fmap f (Cons x xs) = Cons (f x) (fmap f xs)
  19. fmap f (IsText text) = foldr Cons Nil $ fmap f (T.unpack text)
  20.  
  21. list :: [a] -> List a
  22. list = foldr Cons Nil
  23.  
  24. fromText :: T.Text -> List Char
  25. fromText = IsText
  26.  
  27. unList :: List a -> [a]
  28. unList Nil = []
  29. unList (Cons x xs) = x : unList xs
  30. unList (IsText text) = T.unpack text
  31.  
  32. -- This whole facade comes crashing down unless you hide the constructors.
  33. -- I.e. if you don't hide the constructors, it is very easy to write a
  34. -- "function" such that `xs == ys` but `f xs /= f ys`.
  35. -- To prevent this, you have to prevent people from pattern matching the
  36. -- constructors and force access through `unList`.
  37. instance Eq a => Eq (List a) where
  38. xs == ys = unList xs == unList ys
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement