Getting an error: parse error on input ‘Just’ - haskell

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

Related

How do I get 'unpredictable' overloading on a return type working in 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.

Basic Haskell function types?

Super basic question - but I can't seem to get a clear answer. The below function won't compile:
randomfunc :: a -> a -> b
randomfunc e1 e2
| e1 > 2 && e2 > 2 = "Both greater"
| otherwise = "Not both greater"
main = do
let x = randomfunc 2 1
putStrLn $ show x
I'm confused as to why this won't work. Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?
Error:
"Couldn't match expected type ‘b’ with actual type ‘[Char]’"
Not quite. Your function signature indicates: for all types a and b, randomfunc will return something of type b if given two things of type a.
However, randomFunc returns a String ([Char]). And since you compare e1 with 2 each other, you cannot use all a's, only those that can be used with >:
(>) :: Ord a => a -> a -> Bool
Note that e1 > 2 also needs a way to create such an an a from 2:
(> 2) :: (Num a, Ord a) => a -> Bool
So either use a specific type, or make sure that you handle all those constraints correctly:
randomfunc :: Int -> Int -> String
randomFunc :: (Ord a, Num a) => a -> a -> String
Both parameters are type 'a' (Ints) and the return parameter is type 'b' (String)?
In a Haskell type signature, when you write names that begin with a lowercase letter such as a, the compiler implicitly adds forall a. to the beginning of the type. So, this is what the compiler actually sees:
randomfunc :: forall a b. a -> a -> b
The type signature claims that your function will work for whatever ("for all") types a and b the caller throws at you. But this is not true for your function, since it only works on Int and String respectively.
You need to make your type more specific:
randomfunc :: Int -> Int -> String
On the other hand, perhaps you intended to ask the compiler to fill out a and b for you automatically, rather than to claim that it will work for all a and b. In that case, what you are really looking for is the PartialTypeSignatures feature:
{-# LANGUAGE PartialTypeSignatures #-}
randomfunc :: _a -> _a -> _b

Using fsharp-typeclasses to make a function that works on arbitrary monads

I'm trying to implement composM from the paper A pattern for almost compositional functions which accepts an arbitray monad and works on it. In Haskell the code would be:
data Expr =
| Var String
| Abs String Expr
composExprM :: (Monad m) => (Expr -> m Expr) -> Expr -> m Expr
composExprM f e =
case e of
Abs n e -> f e >>= (\e' -> return $ Abs n e')
_ -> return e
I tried using fsharp-typeclasses with the code below:
type Expr =
| Var of string
| Abs of string * Expr
let rec composExprM f e = match e with
| Abs (n, e) -> f e >>= (fun e' -> return' <| Abs (n, e'))
| Var _ -> return' e
But I get type inference errors:
> Could not resolve the ambiguity inherent in the use of the operator 'instance' at or near this program point. Consider using type annotations to resolve the ambiguity.
> Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'instance'. The available overloads are shown below (or in the Error List window). Consider adding further type constraints
> Possible overload: 'static member Return.instance : _Monad:Return * Maybe<'a> -> ('a -> Maybe<'a>)'. Type constraint mismatch. The type
obj
is not compatible with type
Maybe<'a>
The type 'obj' is not compatible with the type 'Maybe<'a>'.
> etc.....
Is what I'm trying to achieve possible with fsharp-typeclasses? Or do I have to restrict the function to only use a specific monad?
Keep in mind that polymorphic functions using this technique should be inline, that's where the "magic" resides.
So, just add the inline keyword after let rec and it will compile.
Please let me know if the function behaves as expected. I will have a look at that paper later.
In the samples you will find many functions defined to work with any Monad.
That was the main motivation when I started this project.

The Type signature lacks an appropriate binding [Haskell]

I have been googling around to find the answer, and even came to a few questions asked here. It seems that this is an ambiguous error and I can't figure out how to solve it in my instance.
The offending code is below:
pos :: (Eq a) => [a] -> a -> Int
pos [] _ = -1
pos (x:xs) y
| not $ elem y (x:xs) = -1
| x == y = 0
| otherwise = 1 + pos xs y
-- Get the same element from another range as one element of the first range.
refPos :: (Eq a) => [a] -> [b] -> a -> b
refPos r1 r2 e1 = r2 !! (r1 `pos` e1)
letterNumber :: (Eq a, Char a) => a -> Int
lettNumber x = refPos ['a'..'z'] [0..25] x
The text of the exact error is:
15:1 The type signature for letterNumber lacks an accompanying binding.
Originally the type signature I put was Char -> Int, but that didn't work (it said something about Eq, but I'm too new too Haskell to interpret it properly). So I changed the type signature to have an Eq class constraint. If someone can point out what is wrong or a workaround, it would be greatly appreciated as this is a doorstop problem to a project I'm working on.
You provide a type signature for letterNumber, but then provide a binding for lettNumber. Note the missing er.
Just rename lettNumber to letterNumber, to match the spelling in the type signature.
Also, the correct type signature for letterNumber is
letterNumber :: Char -> Int

Data initialization and data members change in Haskell

I'm new to Haskell and I cannot figure out how you declare a "Data" type and how you can initialize a variable with that type. I'd also like to know how can I change the values of certain members of that variable. For exaple :
data Memory a = A
{ cameFrom :: Maybe Direction
, lastVal :: val
, visited :: [Direction]
}
Direction is a Data type that contains N,S,E,W
val is a Type int
init :: Int -> a
init n = ((Nothing) n []) gives me the following error:
The function `Nothing' is applied to two arguments,
but its type `Maybe a0' has none
In the expression: ((Nothing) n [])
In an equation for `init': init n = ((Nothing) n [])
how can I fix this ?
UPDATE: That did it, thank you very much, but now i have another issue
move :: val -> [Direction] -> Memory -> Direction
move s cs m | s < m.lastVal = m.cameFrom
| ...
this gives me the following error:
Couldn't match expected type `Int' with actual type `a0 -> c0'
Expected type: val
Actual type: a0 -> c0
In the second argument of `(<)', namely `m . lastVal'
In the expression: s < m . lastVal
UPDATE 2: Again, that helped me a lot, thank you very much
Also, I have another question (sorry for being such a bother)
How do I adress only an element of a type
For example if I have
Type Cell = (Int, Int)
Type Direction = (Cell, Int)
how do I proceed if I want to compare a Cell variable with the Cell element of a Direction variable?
As to the update. The syntax
m.lastVal
and
m.cameFrom
is not what you want. Instead
move s cs m | s < lastVal m = cameFrom m
accessors are just functions, so used in prefix form. The . in Haskell is used for namespace resolution (which is not path dependent) and for function composition
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)
To initialise:
init :: Int -> Memory Int
init n = A {cameFrom = Nothing, lastVal = n, visited = []}
To change values: strictly speaking you don't change values, you return another different value, like this:
toGetBackTo :: Direction -> Memory a -> Memory a
toGetBackTo dir memory = memory {cameFrom = Just dir, visited = dir : visited memory}

Resources