Make function with (Maybe a) parameter "generic" - haskell

let updateFunc = updatedMaybeProperty srcTitle targetTitle :: (Title -> Maybe a) -> Maybe a
_ = updateFunc (titleVersion :: Title -> Maybe Text)
_ = updateFunc (titleYearProduced :: Title -> Maybe Integer)
I get this error in line 3:
• Couldn't match type ‘Text’ with ‘Integer’
Expected type: Title -> Maybe Text
Actual type: Title -> Maybe Integer
• In the first argument of ‘updateFunc’, namely
‘(titleYearProduced :: Title -> Maybe Integer)’
Apparently, in line 2, the compiler infers the type for Maybe a and decides a must always be Text.
How can I prevent this and make updateFunc "generic" so that it works with different types for a?

Try annotating the binding, not the expression.
let updateFunc :: (Title -> Maybe a) -> Maybe a
updateFunc = updatedMaybeProperty srcTitle targetTitle
_ = updateFunc (titleVersion :: Title -> Maybe Text)
_ = updateFunc (titleYearProduced :: Title -> Maybe Integer)

Related

Issue with Map.update Haskell

type Cxt = Map Id (Addr, Type)
data St = St
{ cotxt :: [Cxt] -- ^ Context. }
temp <- gets cotxt
case temp of
[currentCxt] -> modify $ \ st -> st {cotxt = [Map.update (\x -> if x == Nothing then Nothing else Just (addr2,typ2)) id currentCxt]}
(currentCxt:cxts) -> modify $ \ st -> st {cotxt = Map.update (\x -> if x == Nothing then Nothing else Just (addr2,typ2)) id currentCxt:cxts}
I am unable to find the issue as I followed the procedure from here https://caiorss.github.io/Functional-Programming/haskell/data_map.html
Errors at line [currentCxt] & similar errors for the other line as well
1. • Couldn't match type ‘Maybe a0’ with ‘(Addr, Type)’
Expected type: [Cxt]
Actual type: [Map Id (Maybe a0)]
2. • Couldn't match type ‘(Addr, Type)’ with ‘Maybe a0’
Expected type: Maybe (Maybe a0)
Actual type: Maybe (Addr, Type)
• In the expression: Just (addr2, typ2)
In the expression:
if x == Nothing then Nothing else Just (addr2, typ2)
In the first argument of ‘Map.update’, namely
‘(\ x -> if x == Nothing then Nothing else Just (addr2, typ2))’
3. • Couldn't match type ‘(Addr, Type)’ with ‘Maybe a0’
Expected type: Map Id (Maybe a0)
Actual type: Cxt
Well, Map.update takes a function (Addr, Type) -> Maybe (Addr, Type) as it's first argument, but the function you're supplying:
\x -> if x == Nothing then Nothing else Just (addr2,type2)
looks like it's of type:
Maybe (Addr, Type) -> Maybe (Addr, Type)
That seems to be the main problem. Maybe you meant Map.alter in place of Map.update? Though, if you want to unconditionally replace the item at key id with (addr2,typ2), then:
Map.insert id (addr2,typ2) currentCtx
is more straightforward.
Also, as a stylistic note, using id as an identifier in Haskell for anything other than the built-in identity function will be very confusing to other Haskell programmers.

How to create a newtype of parser?

newtype Parser a = PsrOf{
-- | Function from input string to:
--
-- * Nothing, if failure (syntax error);
-- * Just (unconsumed input, answer), if success.
dePsr :: String -> Maybe (String, a)}
I want to create a newtype of Parser to see how it looks like.
I tried
*ParserLib> PsrOf{"hello"}
But it comes up with an error
<interactive>:5:7: error: parse error on input ‘"’
You've already created the type. Now you want to create a value of that type. To do that, you need to call PsrOf with a value of type String -> Maybe (String, a). For example:
newtype Parser a = PsrOf { dePsr :: String -> Maybe (String, a) }
get3 :: String -> Maybe (String, Int)
get3 ('3':xs) = Just (xs, 3)
get3 _ = Nothing -- Any string, including the empty string, that doesn't start with '3'
get3P :: Parser Int
get3P = PsrOf get3
To actually use the parser, you need to extract the function before applying it to a string:
dePsr get3P "38" -- Just ("8", 3)
dePsr get3P "" -- Nothing
dePsr get3P "hello" -- Nothing
Record syntax here is just used to simplify the definition of the type, instead of writing
newtype Parser a = PsrOf (String -> Maybe (String, a))
dePsr :: Parser a -> String -> Maybe (String, a)
dPsr (PsrOf f) = f
The rest of the uses for record syntax (pattern matching or making slightly modified copies of a value) don't really apply usefully to types that wrap a single value.

Haskell No instance for Show

Here is my code:
type Niveles = (Int, Int, Int)
type Persona = (String, Niveles)
type Pocion = (String, [(String, Int, [Efectos])])
type Ingredientes = [(String, Int, [Efectos])]
type Efectos = Niveles -> Niveles
aplicar3 f (a,b,c) = (f a, f b, f c)
invertir3 (a,b,c) = (c,b,a)
fst3 (a,_,_) = a
snd3 (_,b,_) = b
trd3 (_,_,c) = c
personas = [("Harry",(11, 5, 4)), ("Ron",(6,4,6)), ("Hermione",(8,12,2)), ("Draco",(7,9,6))]
f1 (ns,nc,nf) = (ns+1,nc+2,nf+3)
f2 = aplicar3 (max 7)
f3 (ns,nc,nf)
| ns >= 8 = (ns,nc,nf+5)
| otherwise = (ns,nc,nf-3)
misPociones :: [Pocion]
misPociones = [
("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f3])]),
("Multijugos",[("Cuerno de Bicornio en Polvo",10, [invertir3, (\(a,b,c) -> (a,a,c))]),("Sanguijuela hormonal",54,[(aplicar3 (*2)), (\(a,b,c) -> (a,a,c)) ])]),
("Flores de Bach",[("Orquidea Salvaje",8,[f3]), ("Rosita",1,[f1])])]
efectosDePocion pocion = map trd3 (elementos pocion)
elementos :: Pocion -> Ingredientes
elementos (_, ingredientes) = ingredientes
I have a problem in the last piece of code, when I try to use the function "elementos":
elementos ("Felix Felices",[("Escarabajos Machacados",52,[f1,f2]),("Ojo de Tigre Sucio",2,[f3])])
I've got an error message:
<interactive>:311:1:
No instance for (Show ((Int, Int, Int) -> (Int, Int, Int)))
arising from a use of `print'
Possible fix:
add an instance declaration for
(Show ((Int, Int, Int) -> (Int, Int, Int)))
In a stmt of an interactive GHCi command: print it
Can someone explain this to me? How can I fix it?
In short, the function evaluates correctly - the problem is caused by evaluating it in ghci.
Your function call returns a value of type Ingredientes which is a type synonym for [(String, Int, [Efectos])]. ghci tries to print the returned value to the console, so it tries to call show on it. But Efectos is a type synonym for a function. ghci tells you that it doesn't know how to display a function, because it's not a member of the typeclass Show: No instance for (Show ((Int, Int, Int) -> (Int, Int, Int))).
It probably shouldn't concern you - you'd get a similar error by evaluating any function in ghci.
Add to your .hs file the following code
instance Show (a -> b) where
show a= "funcion"
Now ghci will be able to print "funcion" (function)
Good luck!

Returning different values of the same data type:

I'm writing a readValue function that can return any of Value's algebraic data types. The value constructors for Value aren't exported, so how can I return a Value?
Here's the documentation on Value.
Below is the function and the errors it produces:
readValue :: Label -> String -> Value
readValue label valueString =
case label of
"tags" -> (read valueString :: [String])
"text" -> (read valueString :: String)
src/Edit.hs:79:16:
Couldn't match type `Char' with `[Char]'
Expected type: [String]
Actual type: String
In the expression: (read valueString :: String)
In a case alternative: "text" -> (read valueString :: String)
In the expression:
case label of {
"tags" -> (read valueString :: [String])
"text" -> (read valueString :: String) }
You have:
readValue :: Label -> Value
You want:
readValue :: Label -> String -> Value
But:
(read valueString :: [String])
Has type [String] because that’s the type you gave it explicitly. Recall that :: has the lowest precedence. So the compiler is trying to unify String -> [String] with Value. That’s the source of your first error. The second error is caused by the :: String annotation on the second branch of the case, asking the compiler to try to unify String with [String], which too fails.
I suppose you want to wrap these values you’ve read into some of the Value constructors, which are indeed exported by Data.Bson, else you would be trying to return multiple different types from one function. But without knowing more about your problem, I can’t infer what you meant to do.
Here's the solution:
instance Val Value where
val = id
cast' = Just
readValue :: Label -> String -> Value
readValue label valueString =
case label of
"tags" -> val (read valueString :: [String])
"text" -> val (read valueString :: String)

What happens to missing type variables in Church-style core?

This is a bit esoteric, but maddening. In an answer to another question, I noted that in this entirely valid program
poo :: String -> a -> a
poo _ = id
qoo :: (a -> a) -> String
qoo _ = ""
roo :: String -> String
roo = qoo . poo
the type variable a is neither solved nor generalized in the process of checking roo. I'm wondering what happens in the translation to GHC's core language, a Church-style variant of System F. Let me spell things out longhand, with explicit type lambdas /\ and type applications #.
poo :: forall a. [Char] -> a -> a
poo = /\ a -> \ s x -> id # a
qoo :: forall a. (a -> a) -> [Char]
qoo = /\ a -> \ f -> [] # Char
roo :: [Char] -> [Char]
roo = (.) # [Char] # (? -> ?) # [Char] (qoo # ?) (poo # ?)
What on earth goes in the ? places? How does roo become a valid core term? Or do we really get a mysterious vacuous quantifier, despite what the type signature says?
roo :: forall a. [Char] -> [Char]
roo = /\ a -> ...
I've just checked that
roo :: forall . String -> String
roo = qoo . poo
goes through ok, which may or may not mean that the thing typechecks with no extra quantification.
What's happening down there?
Here's the core generated by GHC (after adding some NOINLINE pragmas).
qoo_rbu :: forall a_abz. (a_abz -> a_abz) -> GHC.Base.String
[GblId, Arity=1, Caf=NoCafRefs]
qoo_rbu = \ (# a_abN) _ -> GHC.Types.[] # GHC.Types.Char
poo_rbs :: forall a_abA. GHC.Base.String -> a_abA -> a_abA
[GblId, Arity=1]
poo_rbs = \ (# a_abP) _ -> GHC.Base.id # a_abP
roo_rbw :: GHC.Base.String -> GHC.Base.String
[GblId]
roo_rbw =
GHC.Base..
# (GHC.Prim.Any -> GHC.Prim.Any)
# GHC.Base.String
# GHC.Base.String
(qoo_rbu # GHC.Prim.Any)
(poo_rbs # GHC.Prim.Any)
It seems GHC.Prim.Any is used for the polymorphic type.
From the docs (emphasis mine):
The type constructor Any is type to which you can unsafely coerce any
lifted type, and back.
It is lifted, and hence represented by a pointer
It does not claim to
be a data type, and that's important for the code generator, because
the code gen may enter a data value but never enters a function value.
It's also used to instantiate un-constrained type variables after type
checking.
It makes sense to have such a type to insert in place of un-constrained types, as otherwise trivial expressions like length [] would cause an ambiguous type error.
This is a non-problem. In the signature of roo, the type variable a just does not appear as it stands. An easier example would be the expression
const 1 id
where
id :: forall a.a->a

Resources