Changes between Initial Version and Version 1 of SafeRoles/Pre78GND


Ignore:
Timestamp:
Apr 30, 2015 6:02:47 PM (4 years ago)
Author:
dterei
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • SafeRoles/Pre78GND

    v1 v1  
     1= GND Pre-GHC-7.8 =
     2
     3We will ignore the type-safety issues as they have been resolved, instead we'll just look at the module boundary / abstraction issues.
     4
     5In GHC 7.6 or earlier, assume a library author writes the following `MinList` data type:
     6
     7
     8{{{
     9module MinList (
     10        MinList, newMinList, insertMinList,
     11    ) where
     12
     13data MinList a = MinList a [a] deriving (Show)
     14
     15newMinList :: Ord a => a -> MinList a
     16newMinList n = MinList n []
     17
     18insertMinList :: Ord a => MinList a -> a -> MinList a
     19insertMinList s@(MinList m xs) n | n > m     = MinList m (n:xs)
     20                                 | otherwise = s
     21}}}
     22
     23The `MinList` data type has an invariant (that depends on the `Ord` typeclass for the type parameter `a` that `MinList` is instantiated at) that after initialization it doesn't accept any element less than the initial element.
     24
     25In GHC 7.6 and earlier, we could use GND to violate this invariant:
     26
     27{{{
     28{-# LANGUAGE GeneralizedNewtypeDeriving #-}
     29module Main where
     30
     31import MinList
     32
     33class IntIso t where
     34    intIso :: c t -> c Int
     35
     36instance IntIso Int where
     37    intIso = id
     38
     39newtype Down a = Down a deriving (Eq, IntIso)
     40
     41instance Ord a => Ord (Down a) where
     42    compare (Down a) (Down b) = compare b a
     43
     44fine :: MinList (Down Int)
     45fine = foldl (\x y -> insertMinList x $ Down y) (newMinList $ Down 0) [-1,-2,-3,-4,1,2,3,4]
     46
     47unsafeCast :: MinList (Down Int) -> MinList Int
     48unsafeCast = intIso
     49
     50bad :: MinList Int
     51bad = unsafeCast fine
     52
     53main = do
     54    print bad
     55}}}
     56
     57Essentially, through GND we have created the function `unsafeCast :: MinList (Down Int) -> MinList Int`. This is a function we can't write by hand since we don't have access to the `MinList` constructor and so can't "see" into the data type.
     58
     59== Safe Haskell Pre-GHC-7.8 ==
     60
     61Due to both the type-safety and abstraction issues, GND was considered unsafe in Safe Haskell.