GHC 7.10 - Haskell

Simon Peyton Jones
Microsoft Research
September 2015
 Partial type signatures (Thomas Winant et al)
f :: _ -> Int -> [ _ ]
g :: (_) => a -> a
 API annotations (Alan Zimmerman):
the ability to know exactly where every nonterminal in the original source text appears
 Applicative as a superclass of Monad (finally)
 More robust GMP hook-up (Herbert Valerio
Riedel)
 Preliminary support for Cloud Haskell 'static'
 Plugin API for a SMT solver in the type
inference engine (Iavor Diatchki,
experimental)
 GADT-aware pattern-match
overlap/exhaustiveness warnings (George
Karachalias, Tom Schrjvers et al; see our ICFP
paper)
 Injective type families (Jan Stolarek; see our
HS paper)
 Applicative do-notation (Simon Marlow)
 Implicit-parameter support for call stacks
(Eric Seidel et al)
 Strict Haskell (Johan Tibbell and Adam
Sandberg Eriksson)
 Overloaded record fields (Adam Gundry)
 Kind equalities, and GADTs at the type level
(Richard Eisenberg and Stephanie Weirich)
 Visible type application (Stephanie Weirich,
Richard Eisenberg)
 Type-indexed type representations
 MonadFail
 DWARF-based stack backtraces (Peter
Wortmann)
 A Shake-based build system (Andrey
Mokhov)
 Backpack... (Edward Yang)
head :: [a] -> a
head (x:xs) = x
head []
= error "head of empty list"
ghci> complicated_function 89
*** Exception: head of empty list
 But who called 'head'???????
head :: String -> [a] -> a
head _ (x:xs) = x
head info [] = error ("head of empty list" ++ info)
foogle x y z = ....(head "In foogle" ts)....
 Change in head's type signature
 Every call site must be changed to pass an
informative string
head :: (?cs :: CallStack) => [a] -> a
head (x:xs) = x
head []
= error ("head of empty list\n"
++ showCallStack ?cs)
foogle x y z = ....(head ts)....
ghci> complicated_function 89
*** Exception: Head of empty list
?cs, called at Foo.hs:8:60 in main:Foo
head, called at Foo.hs:10:9 in main:Foo
 Better, but what if you don't know where
'foogle' was called?
head :: (?cs :: CallStack) => [a] -> a
head (x:xs) = x
head []
= error ("head of empty list\n"
++ showCallStack ?cs)
foogle :: (?cs :: CallStack) => Int -> Int
foogle x = ....(head e)....
 Re-uses existing notation
 Easy to implement: the constraint solver is
the only bit that changes
 Zero impact on transformation, optimisation,
code generation, etc
 Decent records are probably GHC's longestasked-for feature
 It's a swamp: many designs, all with complex
tradeoffs.
 We have finally plumped for a simple,
modular design, with three pieces:
1. Allow duplicate field labels
2. Record classes for overloading
3. Overloaded labels for convenience
data T = MkT { x, y :: Int }
data S = MkS { x :: Bool, z :: Int }
 Record construction and pattern matching
are unaffected
f :: S -> T
f (MkS { x = v } = MkS { x = True, y = v }
 Duplicated record selectors are ambiguous;
but NB selective import
module A where
import M( T(MkT, x, y) )
f r = x r + y r
-- But not S
class HasField (x :: Symbol) r where
type FieldType x r
getField :: Proxy# x -> r -> FieldType x r
 Every field gives rise to a new instance
instance HasField "x" T where
type FieldType "x" T = Int
getField (MkT { x = v }) = v
 Now selection is overloaded:
f :: T -> Int
f r = getField (Proxy :: Proxy "x") r + 1
-- Gets field "x" from a T record
class IsLabel (x :: Symbol) a where
fromLabel :: a
 Syntax "#x" expands to (fromLabel @ "x" @t)
instance (HasField x r, a ~ FieldType x r)
=> IsLabel x (r -> a) where
fromLabel = getField (Proxy :: Proxy x)
 So (#x r) would expand (via the instance) to
getField (Proxy :: Proxy "x")
just as we want
 But the instance is library code; we can change it if
we want #x to mean a lens
class Typeable a where
typeRep :: Proxy a -> TypeRep
data Dynamic where
Dynamic :: TypeRep -> a -> Dynamic
toDyn :: forall a. Typeable a => a -> Dynamic
toDyn x = Dynamic trep x
where
trep :: TypeRep
trep = typeRep (Proxy :: Proxy a)
data Dynamic where
Dynamic :: TypeRep -> a -> Dynamic
fromDynamic :: forall a. Typeable a =>
Dynamic -> Maybe a
fromDynamic (Dynamic trx x)
| trx == trr = x
| otherwise = Nothing
where
trr = typeRep (Proxy :: Proxy a)
 Does not typecheck because (trx == trr)
tells the type system nothing
data Dynamic where
Dynamic :: TypeRep -> a -> Dynamic
fromDynamic :: forall a. Typeable a =>
Dynamic -> Maybe a
fromDynamic (Dynamic trx x)
| trx == trr = unsafeCoerce x
| otherwise = Nothing
where
trr = typeRep (Proxy :: Proxy a)
 And yet, comparing TypeReps should tell us
something! After all, they were built by the
compiler!
class Typeable a where
typeRep :: TypeRep a
eqT :: TypeRep a -> TypeRep b -> Maybe (a :~: b)
data a :~: b where
Refl :: a :~: a
 Now, comparing TypeReps does tell us
something!
data Dynamic where
Dynamic :: TypeRep a -> a -> Dynamic
eqT :: TypeRep a -> TypeRep b -> Maybe (a :~: b)
fromDynamic :: forall a. Typeable a =>
Dynamic -> Maybe a
fromDynamic (Dynamic trx x)
= case eqT trx (typeRep :: TypeRep a) of
Just Refl -> Just x
Nothing
-> Nothing
 From TypeRep to (TypeRep a) allows us to do
type-safe reflection
 Useful for Cloud Haskell style applications
 Smaller trusted code base. I think GHC
implementors only, rather than library
authors
 Interestingly, it turns out to need Richard
Eisenberg's kind-level equalities!
 GHC is flourishing
 lots of users
 lots of innovation
 lots of contributors
Trac tickets over 10,000
 GHC is more and more a community project,
both in leadership and execution
 This is not a bad thing. But it relies on people
actually stepping up.
Introducing the new Well Typed GHC support team:
 Austin Seipp
 Ban Gamari
Major role
Not so much doing, but
enabling others to do
Bottom line
GHC and
(especially) its ecosystem
(cabal, Hackage, Haskell Platform...)
badly need your help
 type system
 optimisation
 code generation for
many platforms
 SIMD instructions
 dynamic linking
 GHCi
 the GHC API
 plugins
 FFI
concurrency, STM
Cloud Haskell
the build system
packages
garbage collection,
finalisers
 run-time system,
scheduling
 profiling
 ....and more...





 Profiling and debugging
 Connection between profiler output and -ddump-simpl for autogenerated SCCs. Use DWARF annotations? (Norman)
 Sample-based profiling. DWARF will give this. (Lennart)
 Free stack traces: always on. DWARF will give this. (Johan)
 Core-to-Core API is hard to use (tall guy, glasses,
black hair)
 Inlining reporting (John Wigely)
 Show instances for GHC internals (Johan)
 Code generation something ...