Issue with Map.update Haskell - 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.

Related

Make function with (Maybe a) parameter "generic"

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)

read::Int not working in Haskell in example

Here is the problem. It looks simple yet
main = do
s <- getContents
let list = map (read::Int) (words s)
print list
Couldn't match expected type `Int' with actual type `String -> a0'
Probable cause: `read' is applied to too few arguments
In the first argument of `map', namely `(read :: Int)'
In the expression: map (read :: Int) (words s)
The problem was that I thought :: is like casting and I have to put the return type. The solution was to add full wanted |function signature instread.
read is a function (of type Read a => String -> a), so it can't have type Int. You could do read :: String -> Int, or you could put a type signature on list rather than read, so you get:
let list :: [Int]
list = map read (words s)

Infinite Square Roots : Couldn't match expected type & cannot construct the infinite type

Sorry for what's probably an idiot question - trying to learn Haskell at the moment;
I'm trying to build a basic function that will create an infinite list of square roots on a number, so I can get practice with the take function and how it works.
I wrote the following code;
infisqrt x = infisqrt'((x :: Float) [])
-- helper method
infisqrt' x xs = infisqrt'(sqrt(x) (xs ++ [(sqrt(x))]))
However, this is returning with two errors when trying to load the library;
:l isq
isq.hs:1:24:
Couldn't match expected type ‘[t0] -> a’ with actual type ‘Float’
Relevant bindings include
infisqrt :: Float -> [a] -> t (bound at isq.hs:1:1)
The function ‘x :: Float’ is applied to one argument,
but its type ‘Float’ has none
In the first argument of ‘infisqrt'’, namely ‘((x :: Float) [])’
In the expression: infisqrt' ((x :: Float) [])
isq.hs:5:33:
Occurs check: cannot construct the infinite type: a ~ [a] -> a
Relevant bindings include
xs :: [a] (bound at isq.hs:5:13)
x :: a (bound at isq.hs:5:11)
infisqrt' :: a -> [a] -> t (bound at isq.hs:5:1)
In the first argument of ‘sqrt’, namely ‘(x)’
In the first argument of ‘infisqrt'’, namely
‘(sqrt (x) (xs ++ [(sqrt (x))]))’
Can anyone let me know where I'm going wrong with this?
Haskell function invocation doesn't use parentheses. It looks like you're expecting this:
infisqrt x = infisqrt'((x :: Float) [])
to mean "pass x and [] as arguments to inifsqrt." However, to the compiler, it actually means "pass [] as the first argument to x, and then pass the result to infisqrt'." If you take the extra parentheses out, you should start getting traction:
infisqrt x = infisqrt' (x :: Float) []
(remember, you've got the same thing going on in infisqrt''s definition)
As a side note, it's typically preferable to put arguments' types in a function type declaration:
infisqrt :: Float -> [Float]
infisqrt x = infisqrt' x []

type error in func declaration

I do:
Prelude> "sone" ++ "otehr"
"soneotehr"
But such code:
addOneToElement :: [a] -> [a]
addOneToElement element = element ++ "next"
main = do
let s = addOneToElement("some")
putStrLn s
produces this output:
all_possible_combinations.hs:22:37:
Couldn't match expected type `a' against inferred type `Char'
`a' is a rigid type variable bound by
the type signature for `addOneToElement'
at all_possible_combinations.hs:21:20
Expected type: [a]
Inferred type: [Char]
In the second argument of `(++)', namely `"next"'
In the expression: element ++ "next"
Why I get this error and how I can fix it?
Your type signature should be:
addOneToElement :: [Char] -> [Char]
(Or more simply, addOneToElement :: String -> String)
The "a" in your type signature is a wildcard - it can match anything. However you are trying to concatenate a list of Char to a list of anything - and there is no way to do that.
Why are you using a type variable here anyway? The only type that can match is Char, since the second operand of (++) is fixed to [Char] ("next").

Why is GHC complaining about wrong type?

This little function checks a (finite) Brainfuck string for validity. It check's whether the [ and ] are balanced. The code is very straightforward and written to be tail-recursive:
-- checks Brainfuck for validity.
validateBrainfuck :: Monad m => String -> m String
validateBrainfuck s = maybe (return s) (fail . fromJust) (validate s 0) where
validate :: String -> Int -> Maybe String -- Here inversed: String means error
validate (']':_ ) 0 = Just "Too many closing brackets"
validate (']':xs) c = validate xs (pred c)
validate ('[':xs) c = validate xs (succ c)
validate ( x :xs) c = validate xs c
validate [] 0 = Nothing
validate [] _ = Just "Too many opening brackets"
Now, GHC complains about typing issues:
Brainfuck.hs:62:58:
Couldn't match expected type `Maybe String'
against inferred type `[Char]'
Expected type: Maybe (Maybe String)
Inferred type: Maybe String
In the third argument of `maybe', namely `(validate s 0)'
In the expression:
maybe (return s) (fail . fromJust) (validate s 0)
Maybe I'm just too silly to figure out what went wrong, but this looks very weird for me.
Look at the type of maybe and think what it should do:
maybe :: b -> (a -> b) -> Maybe a -> b
If the maybe value contains no result (i.e. Nothing), maybe returns the b argument.
Otherwise - when Just a is given - it applies the given function to the valid result. We don't need any fromJust extraction here.
Your code just becomes
maybe (return s) fail (validate s 0)

Resources