SHARE
TWEET

Untitled

a guest Jul 17th, 2019 57 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top