How do I get 'unpredictable' overloading on a return type working in Haskell? - haskell

I have some type instances. Let's call them A, B, and C. They all are instances of typeclass X. Now I would like to create a seperate function create that creates an instance of A, B or C given some input (let's say a string). The type system cannot know what input is going to give what type. That's the thing Haskell doesn't like, and I think I know the answer, but I want to be sure. The current error I'm getting is:
• Couldn't match expected type ‘c’ with actual type ‘GCCCommand’
‘c’ is a rigid type variable bound by
the type signature for:
compiler :: forall c. CompilerCommand c => String -> c
at src/System/Command/Typed/CC.hs:29:1-44
• In the expression: gcc path
In an equation for ‘compiler’:
compiler path
| exe == "g++" || exe == "gcc" || exe == "cc" || exe == "cpp"
= gcc path
where
exe = takeFileName path
• Relevant bindings include
compiler :: String -> c
(bound at src/System/Command/Typed/CC.hs:31:1)
Does that mean, as I suspect, that it is not possible to overload on return type in this particular case because the compiler can't know upfront how the data will look in memory? How would you go to implement this function? I was thinking about creating something like the following:
data SuperX = SuperA A | SuperB B | SuperC C
create :: String -> SuperX
-- create can now be implemented
instance X SuperX where
-- a lot of boilerplate code ...
However, the boilerplate code suggests that it can be done better. Is this really the best way for doing it?

It depends what you need to do with it.
If your later processing doesn't care if it gets an A, a B, or C, just that it gets something that implements X...
restOfProgram :: X a => a -> ThingIWantToCompute
Then you could use continuation passing:
parseABC :: (X a => a -> r) -> String -> Maybe r
parseABC f "A" = Just (f A)
parseABC f ('B':xs) = Just (f (B xs))
parseABC f ('C':xs) = Just (f (C (read xs)))
parseABC _ _ = Nothing
Or an existential data wrapper:
data SomeX where
SomeX :: X t => t -> SomeX
parseABC :: String -> Maybe SomeX
parseABC "A" = Just (SomeX A)
parseABC ('B':xs) = Just (SomeX (B xs))
parseABC ('C':xs) = Just (SomeX (C (read xs)))
parseABC _ _ = Nothing
restOfProgram' :: SomeX -> ThingIWantToCompute
restOfProgram' (SomeX t) = restOfProgram t
If the later processing has different paths for A, B or C, you probably want to return a sum type like SuperX.

Related

couldn't match expected type (newtype)

I'm working on a function
createTypeBoard :: (Int, Int) -> CellType -> Board
using these types
newtype Board = Board [(Cell, CellType)] deriving(Eq)
data CellType = Mine
| Flag
| Void
| Enumerated Int
| Undiscovered
deriving Eq
type Cell = (Int, Int)
createTypeBoard (2,2) Mine should be: Board [((1,1), X), ((1,2), X), ((2,1), X), ((2,2), X)]
(X is the show instance of Mine)
my idea was to use zip:
createTypeBoars (a, b) c = zip (createCells (a, b)) [c]
but I keep getting an error
• Couldn't match expected type ‘Board’
with actual type ‘[(Cell, CellType)]’
• In the expression: zip (createCells (a, b)) [Flag]
In an equation for ‘createTypeBoard’:
createTypeBoard (a, b) Flag = zip (createCells (a, b)) [Flag]
Board basically is [(Cell, CellType)] so I don't really get what the problem is :(
You declared Board with newtype, but you're trying to use it as if you declared it with type. Two choices to fix it:
Declare board like this instead: type Board = [(Cell, CellType)]
Use the Board data constructor in createTypeBoard, like this: createTypeBoard (a, b) c = Board $ zip (createCells (a, b)) [c]
For more information on the difference between type and newtype, which may affect your decision on which fix to go with, see Haskell type vs. newtype with respect to type safety and/or The difference between type and newtype in Haskell.

Getting an error: parse error on input ‘Just’

data Type = Nat | Bool | App Type Type | Var String
deriving (Eq, Show)
type Substitution = [(String, Type)]
apply :: Substitution -> Type -> Type
apply s Nat = Nat
apply s Bool = Bool
apply s Var c = case (lookup s c) of
Nothing -> (Var c)
Just v -> v
But the compilers give me the error "error: parse error on input ‘Just’
"
What am I doing wrong?
I can not reproduce the error locally, so my guess is that you used tabs an spaces, if you however copy paste your code into the editor, it should "work". In that case we however receive another error:
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( tmp.hs, interpreted )
tmp.hs:7:1: error:
Equations for ‘apply’ have different numbers of arguments
tmp.hs:7:1-17
tmp.hs:(9,1)-(11,29)
Failed, modules loaded: none.
This is due to the fact that you write:
apply s Var c = -- ...
and Haskell assumes that you here wrote three parameters: s, Var, and c, but the c of course belongs to the Var data constructor. We can fix this with a pair of brackets. Furthermore you call lookup in the wrong way: lookup has type lookup :: Eq a => a -> [(a, b)] -> Maybe b, so the first argument is the key (here c), and the second argument is the lookup table s. So we can fix this with:
apply :: Substitution -> Type -> Type
apply s Nat = Nat
apply s Bool = Bool
apply s (Var c) = case (lookup c s) of
Nothing -> (Var c)
Just v -> v
Note that you can get rid of the case pattern matching, and use for instance fromMaybe :: a -> Maybe a -> a instead:
import Data.Maybe(fromMaybe)
apply :: Substitution -> Type -> Type
apply s Nat = Nat
apply s Bool = Bool
apply s d#(Var c) = fromMaybe d (lookup c s)
We can furthermore group the Nat and Bool case together:
import Data.Maybe(fromMaybe)
apply :: Substitution -> Type -> Type
apply s d#(Var c) = fromMaybe d (lookup c s)
apply s t = t
This given of course that in case the Type is not a Var c pattern, we should return that Type.
Perhaps you need to call apply recursively as well, since the substitution can result into another Var (and thus you have to do extra lookups). This will however change the function semantically (!), so I am not sure if that is a requirement.
I got an error about the number of args to apply and about the types in lookup, but this code typechecks:
data Type = Nat | Bool | App Type Type | Var String
deriving (Eq, Show)
type Substitution = [(String, Type)]
apply :: Substitution -> Type -> Type
apply s Nat = Nat
apply s Bool = Bool
apply s (Var c) = case (lookup c s) of
Nothing -> (Var c)
Just v -> v
Note the parentheses around Var c and the order of lookup c s

Binary instance for Static Pointers

I have the following data type
data Foo a b = A (StaticPtr (a -> b)) deriving (Generic, Typeable)
I want to generate the Binary instance for this type so I can use this function on a remote node.
However, using automatic Binary instantiation doesn't work here:
instance (Binary a, Binary b) => Binary (Foo a b)
This results in
• Could not deduce (Binary (StaticPtr (a -> b)))
arising from a use of ‘binary-0.8.5.1:Data.Binary.Class.$dmput’
from the context: (Binary a, Binary b)
bound by the instance declaration
at /Users/abhiroop/Haskell/snape/app/Spec.hs:23:10-49
• In the expression:
binary-0.8.5.1:Data.Binary.Class.$dmput #Foo a b
In an equation for ‘binary-0.8.5.1:Data.Binary.Class.put’:
binary-0.8.5.1:Data.Binary.Class.put
= binary-0.8.5.1:Data.Binary.Class.$dmput #Foo a b
In the instance declaration for ‘Binary (Foo a b)’
• Could not deduce (Binary (StaticPtr (a -> b)))
arising from a use of ‘binary-0.8.5.1:Data.Binary.Class.$dmget’
from the context: (Binary a, Binary b)
bound by the instance declaration
at /Users/abhiroop/Haskell/snape/app/Spec.hs:23:10-49
• In the expression:
binary-0.8.5.1:Data.Binary.Class.$dmget #Foo a b
In an equation for ‘binary-0.8.5.1:Data.Binary.Class.get’:
binary-0.8.5.1:Data.Binary.Class.get
= binary-0.8.5.1:Data.Binary.Class.$dmget #Foo a b
In the instance declaration for ‘Binary (Foo a b)’
How do I auto generate the Binary instance here?
You can serialize a StaticPtr as a Fingerprint via staticKey and deserialize it via unsafeLookupStaticPtr below it.
You can't define a Binary instance for StaticPtr (even if you wrap it in a newtype to avoid orphans) because the lookup cannot be done purely. But you can still define and use the serializer and deserializer as regular, nonoverloaded functions.
Li-yao Xia's answer is correct. But I had to change my data types, in general, to pass them remotely. I am writing my changes here so it might be useful if someone wants to send a function remotely, there isn't many resources on this online.
So instead of having
data Foo a b = A (StaticPtr (a -> b))
I have changed my data types to look like this:
data Foo a b = A (a -> b)
or to simplify
data Foo f = A f
Here f is the function I want to send remotely.
So taking a simple example of a function like (+ 1) and imagine I want to map this over a list [1,2,3] which is present remotely. My code becomes like this:
main :: IO [Int]
main = do
let list = [1,2,3]
a = static (A (+ 1)) :: StaticPtr (Foo (Int -> Int))
t = staticKey a
-- assuming you sent t to the remote node
-- code on the remote node
x <- unsafeLookupStaticPtr t
case x of
Just sptr -> case deRefStaticPtr sptr of
A f -> return $ map f list
_ -> error "Task undefined"
Nothing -> error "Wrong function serialized"

How do I extract information from inner parameters in Haskell?

In most of programming languages that support mutable variables, one can easily implement something like this Java example:
interface Accepter<T> {
void accept(T t);
}
<T> T getFromDoubleAccepter(Accepter<Accepter<T>> acc){
final List<T> l = new ArrayList<T>();
acc.accept(new Accepter<T>(){
#Override
public void accept(T t) {
l.add(t);
}
});
return l.get(0); //Not being called? Exception!
}
Just for those do not understand Java, the above code receives something can can be provided a function that takes one parameter, and it supposed to grape this parameter as the final result.
This is not like callCC: there is no control flow alternation. Only the inner function's parameter is concerned.
I think the equivalent type signature in Haskell should be
getFromDoubleAccepter :: (forall b. (a -> b) -> b) -> a
So, if someone can gives you a function (a -> b) -> b for a type of your choice, he MUST already have an a in hand. So your job is to give them a "callback", and than keep whatever they sends you in mind, once they returned to you, return that value to your caller.
But I have no idea how to implement this. There are several possible solutions I can think of. Although I don't know how each of them would work, I can rate and order them by prospected difficulties:
Cont or ContT monad. This I consider to be easiest.
RWS monad or similar.
Any other monads. Pure monads like Maybe I consider harder.
Use only standard pure functional features like lazy evaluation, pattern-matching, the fixed point contaminator, etc. This I consider the hardest (or even impossible).
I would like to see answers using any of the above techniques (and prefer harder ways).
Note: There should not be any modification of the type signature, and the solution should do the same thing that the Java code does.
UPDATE
Once I seen somebody commented out getFromDoubleAccepter f = f id I realize that I have made something wrong. Basically I use forall just to make the game easier but it looks like this twist makes it too easy. Actually, the above type signature forces the caller to pass back whatever we gave them, so if we choose a as b then that implementation gives the same expected result, but it is just... not expected.
Actually what came up to my mind is a type signature like:
getFromDoubleAccepter :: ((a -> ()) -> ()) -> a
And this time it is harder.
Another comment writer asks for reasoning. Let's look at a similar function
getFunctionFromAccepter :: (((a -> b) -> b) -> b) -> a -> b
This one have an naive solution:
getFunctionFromAccepter f = \a -> f $ \x -> x a
But in the following test code it fails on the third:
exeMain = do
print $ getFunctionFromAccepter (\f -> f (\x -> 10)) "Example 1" -- 10
print $ getFunctionFromAccepter (\f -> 20) "Example 2" -- 20
print $ getFunctionFromAccepter (\f -> 10 + f (\x -> 30)) "Example 3" --40, should be 30
In the failing case, we pass a function that returns 30, and we expect to get that function back. However the final result is in turn 40, so it fails. Are there any way to implement doing Just that thing I wanted?
If this can be done in Haskell there are a lot of interesting sequences. For example, tuples (or other "algebraic" types) can be defined as functions as well, since we can say something like type (a,b) = (a->b->())->() and implement fst and snd in term of this. And this, is the way I used in a couple of other languages that do not have native "tuple" support but features "closure".
The type of accept is void accept(T) so the equivalent Haskell type is t -> IO () (since every function in Java is essentially IO). Thus getFromDoubleAccepted can be directly translated as
import Data.IORef
type Accepter t = t -> IO ()
getFromDoubleAccepter :: Accepter (Accepter a) -> IO a
getFromDoubleAccepter acc = do
l <- newIORef $ error "Not called"
acc $ writeIORef l
readIORef l
If you want an idiomatic, non-IO solution in Haskell, you need to be more specific about what your actual end goal is besides trying to imitate some Java-pattern.
EDIT: regarding the update
getFromDoubleAccepter :: ((a -> ()) -> ()) -> a
I'm sorry, but this signature is in no way equal to the Java version. What you are saying is that for any a, given a function that takes a function that takes an a but doesn't return anything or do any kind of side effects, you want to somehow conjure up a value of type a. The only implementation that satisfies the given signature is essentially:
getFromDoubleAccepter :: ((a -> ()) -> ()) -> a
getFromDoubleAccepter f = getFromDoubleAccepter f
First, I'll transliterate as much as I can. I'm going to lift these computations to a monad because accept returns void (read () in Haskell-land), which is useless unless there is some effect.
type Accepter m t = t -> m ()
getFromDoubleAccepter :: (MonadSomething m) => Accepter m (Accepter m t) -> m t
getFromDoubleAccepter acc = do
l <- {- new mutable list -}
acc $ \t -> add l t
return (head l)
Of course, we can't make a mutable list like that, so we'll have to use some intuitive sparks here. When an action just adds an element to some accumulator, I think of the Writer monad. So maybe that line should be:
acc $ \t -> tell [t]
Since you are simply returning the head of the list at the end, which doesn't have any effects, I think the signature should become:
getFromDoubleAccepter :: Accepter M (Accepter M t) -> t
where M is an appropriate monad. It needs to be able to write [t]s, so that gives us:
type M t = Writer [t]
getFromDoubleAccepter :: Accepter (M t) (Accepter (M t) t) -> t
And now the type of this function informs us how to write the rest of it:
getFromDoubleAccepter acc =
head . execWriter . acc $ \t -> tell [t]
We can check that it does something...
ghci> getFromDoubleAccepter $ \acc -> acc 42
42
So that seems right, I guess. I'm still a bit unclear on what this code is supposed to mean.
The explicit M t in the type signature is a bit aesthetically bothersome to me. If I knew what problem I was solving I would look at that carefully. If you mean that the argument can be a sequence of commands, but otherwise has no computational features available, then you could specialize the type signature to:
getFromDoubleAccepter :: (forall m. (Monad m) => Accepter m (Accepter m t)) -> t
which still works with our example. Of course, this is all a bit silly. Consider
forall m. (Monad m) => Accepter m (Accepter m t))
= forall m. (Monad m) => (t -> m ()) -> m ()
The only thing a function with this type can do is call its argument with various ts in order and then return (). The information in such a function is completely characterized[1] by those ts, so we could just as easily have used
getFromDoubleAccepter :: [t] -> t
getFromDoubleAccepter = head
[1] As long as I'm going on about nothing, I might as well say that that is not quite accurate in the face of infinity. The computation
crazy :: Integer -> Accepter m (Accepter m Integer)
crazy n acc = crazy (n+1) >> acc n
can be used to form the infinite sequence
... >> acc 3 >> acc 2 >> acc 1 >> acc 0
which has no first element. If we tried to interpret this as a list, we would get an infinite loop when trying to find the first element. However this computation has more information than an infinite loop -- if instead of a list, we used the Last monoid to interpret it, we would be able to extract 0 off the end. So really
forall m. (Monad m) => Accepter m (Accepter m t)
is isomorphic to something slightly more general than a list; specifically a free monoid.
Thanks to the above answers, I finally concluded that in Haskell we can do some different things than other languages.
Actually, the motivation of this post is to translate the famous "single axiom classical logic reduction system". I have implemented this in some other languages. It should be no problem to implement the
Axiom: (a|(b|c)) | ((d|(d|d)) | ((e|b) | ((a|e) | (a|e))))
However, since the reduction rule looks like
Rule: a|(b|c), a |-- c
It is necessary to extract the inner parameter as the final result. In other languages, this is done by using side-effects like mutable slots. However, in Haskell we do not have mutable slots and involving IO will be ugly so I keep looking for solutions.
In the first glance (as show in my question), the getFromDoubleAccepter f = f id seems nonsense, but I realise that it actually work in this case! For example:
rule :: (forall r.a -> (b -> c -> r) -> r) -> a -> c
rule abc a = abc a $ flip const
The trick is still the same: since the existential qualification hides r from the caller, and it is up to the callee to pick up a type for it, we can specify c to be r, so we simply apply the given function to get the result. On the other hand, the given function has to use our input to produce the final answer, so it effectively limiting the implementation to what we exactally want!
Putting them together, let's see what we can do with it:
newtype I r a b = I { runI :: a -> b -> r }
rule :: (forall r. I r a (I r b c)) -> a -> c
rule (I abc) a = abc a (I (\b c -> c))
axiom :: I r0 (I r1 a (I r2 b c))
(I r0 (I r3 d (I r3 d d))
(I r4 (I r2 e b) (I r4 (I r1 a e) (I r1 a e))))
axiom = let
a1 (I eb) e = I $ \b c -> eb e b
a2 = I $ \d (I dd) -> dd d d
a3 (I abc) eb = I $ \a e -> abc a (a1 eb e)
a4 abc = I $ \eb aeae -> runI a2 (a3 abc eb) aeae
in I $ \abc (I dddebaeae) -> dddebaeae a2 (a4 abc)
Here I use a naming convention to trace the type signatures: a variable name is combinded by the "effective" type varialbes (means it is not result type - all r* type variable).
I wouldn't repeat the prove represented in the sited essay, but I want to show something. In the above definition of axiom we use some let bindings variables to construct the result. Not surprisingly, those variables themselves can be extracted by using rule and axiom. let's see how:
--Equal to a4
t4 :: I r0 a (I r1 b c) -> I r2 (I r1 d b) (I r2 (I r0 a d) (I r0 a d))
t4 abc = rule axiom abc
--Equal to a3
t3 :: I r0 a (I r1 b c) -> I r1 d b -> I r0 a d
t3 abc eb = rule (t4 abc) eb
--Equal to a2
t2 :: I r a (I r a a)
t2 = rule (t3 axiom (t3 (t4 axiom) axiom)) axiom
--Equal to a1
t1 :: I r a b -> a -> I r b c
t1 ab a = rule (t3 t2 (t3 (t3 t2 t2) ab)) a
One thing left to be proved is that we can use t1 to t4 only to prove all tautologies. I feel it is the case but have not yet proved it.
Compare to other languages, the Haskell salutation seems more effective and expressive.

Overlapping Pattern Match warning with custom data types

I'm translating several programs from Standard ML to Haskell for a class, and I'm confused about the way Haskell is parsing this pattern matching.
I have this data type:
data Term = A | B
| F Term | G Term | H Term Term
| Var String
deriving (Show)
And this is part of the function I am defining:
unify :: [(Term, Term)] -> Bool
-- argument represents a list of term equations,
-- result indicates whether they have a solution
unify nil = True
unify ((A, A):eqns) = unify eqns
unify ((B, B):eqns) = unify eqns
unify ((F(t1), F(t2)):eqns) = unify((t1,t2):eqns)
unify ((G(t1), G(t2)):eqns) = unify((t1,t2):eqns)
unify ((H s1 t1, H s2 t2):eqns) = unify((s1,s2):(t1,t2):eqns)
unify ((Var v1, t):eqns) =
(case t of
Var v2 -> if v1 == v2 then unify(eqns)
else unify(map (substEqn v1 t) eqns)
_ -> unify(map (substEqn v1 t) eqns))
unify ((t, Var v):eqns) = unify(map (substEqn v t) eqns)
unify _ = False
ghci gives me this output when I import the module:
Warning: Pattern match(es) are overlapped
In an equation for `unify':
unify ((A, A) : eqns) = ...
unify ((B, B) : eqns) = ...
unify ((F (t1), F (t2)) : eqns) = ...
unify ((G (t1), G (t2)) : eqns) = ...
...
I certainly understand how pattern matching works, but I don't understand why Haskell considers these four arguments identical. They are different data types, so shouldn't they not be equivalent patterns? This worked in Standard ML, but something must be lost in translation. Thanks for the help!
I am not sure what nil is (in the first pattern), but I assume you have the empty list in mind. If that is the case, replacing it with [] will do the trick and your pattern matching problem goes away.

Resources