Code for paper "Implicit configurations"
I am trying to run this code in ghci
:
http://www.cs.rutgers.edu/~ccshan/prepose/Prepose.hs
This is the code associated with Functional Gem: Implicit Configurations
http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf
I'm sure I am missing some LANGUAGE
pragmas ... I am getting the following error:
Prepose.hs:39:1: Parse error in pattern: normalize
Also, are there any hacker packages associated with this article?
source to share
You cannot apply a type signature to a function definition template. This is the syntactically correct way of writing:
normalize :: (Modular s a, Integral a) => a -> M s a
normalize a = M (mod a (modulus (__ :: s))) :: M s a
However, this will not work. What you really want is to reference a variable of type s in the function's type signature. This can be done using the ScopedTypeVariables extension, which requires explicit quantification:
normalize :: forall a s. (Modular s a, Integral a) => a -> M s a
normalize x = M (Mod x (modulus (__ :: s)))
As a suggestion for improving the code, I recommend using the tagged library:
import Data.Proxy
modulus :: (Modular s a) => Proxy s -> a
This allows you to do without ugly blanks. Another way to write it down:
modulus :: (Modular s a) => Tagged s a
It also gives you a nice conceptual benefit: you now have two types: Mod
for modular values and Tagged
for their modules. You can also define the type by giving it a nicer name:
newtype Mod s a = Mod { residue :: a }
newtype Modulus s a = Modulus { modulus :: a }
All this aside, if you want to use this I recommend what ocharles said: Use the reflection library .
source to share
I can't help with the code problem, but Edward Kemat's `reflection ' library is based on this article.
source to share
This completes the example from the article using the library reflection
. I am basing this example on the example Monoid
in the library source.
data M a s = M a -- Note the phantom comes *after* the concrete
-- In `normalize` we're tying the knot to get the phantom types to align
-- note that reflect :: Reifies s a => forall proxy. proxy s -> a
normalize :: (Reifies s a, Integral a) => a -> M a s
normalize a = b where b = M (mod a (reflect b))
instance (Reifies s a, Integral a) => Num (M a s) where
M a + M b = normalize (a + b)
...
withModulus :: Integral a => a -> (forall s. Reifies s a => M a s) -> a
withModulus m ma = reify m (runM . asProxyOf ma)
where asProxyOf :: f s -> Proxy s -> f s
asProxyOf a _ = a
source to share