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

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 []

Related

Haskell, using function with list comprehensions

I am trying to accomplish the following:
slice :: Int -> Int -> [a] -> [a]
slice from to xs = take (to - from + 1) (drop from xs)
trimBoard :: Board -> Int -> Board
trimBoard s y = slice ((y*3)) (((y+1)*3)-1) s
getBox :: Board -> Int -> Int -> [Sequence]
getBox s y x = [ (trimBoard c x) | c <- (trimBoard s y)]
Specifically, I'm trying to run a function, take the result [[int]], then map another function onto that result. Which haskell appearantly abhors, and I need to use some combination of "lambda functions" and other wizardry I cant read or comprehend at all to get this chugging along.
Is there any simple way to do this that wont require a 7 month course in mathematical function syntax?
As mentioned above, the result, board, is [[int]], and sequence is simply [int].
The errors it produces are
sudoku.hs:139:19: error:
• Couldn't match type ‘[Int]’ with ‘Int’
Expected type: Sequence
Actual type: Board
• In the expression: (trimBoard c x)
In the expression: [(trimBoard c x) | c <- (trimBoard s y)]
In an equation for ‘getBox’:
getBox s y x = [(trimBoard c x) | c <- (trimBoard s y)]
sudoku.hs:139:29: error:
• Couldn't match type ‘Int’ with ‘[Int]’
Expected type: Board
Actual type: Sequence
• In the first argument of ‘trimBoard’, namely ‘c’
In the expression: (trimBoard c x)
In the expression: [(trimBoard c x) | c <- (trimBoard s y)] Failed, modules loaded: none.
It seems you have written all your functional code correctly but have not correctly specified your type signatures. trimBoard expects a Board as its first argument, but you have passed it c which is a single row.
What you may be complaining about is that trimBoard ought to work perfectly well if you pass it a single row instead of a complete board. And indeed it does, you just need to learn how to say so:
trimBoard :: [a] -> Int -> [a]
That it, trimBoard takes a list of any type, and an Int, and returns a list of that same type. Now you are not restricted to passing lists of lists of Int, and everything works fine.
You could also have omitted the type signature of trimBoard and Haskell would have inferred this one, which is the most general one. (But it is good to write type signatures and learn how to do so -- in fact, with practice, this becomes an invaluable tool that I miss dearly in other languages).

How does Haskell's type system generate this error?

In my ventures through Haskell, I find that when I make a mistake with types in my code, I have a tough time trying to parse what it is that I did wrong and the compiler is complaining about. I think this is because of partial type inference before the compiler finds something wrong.
Of course, I'm used to languages where the type mismatches are very obvious. e.g. something along the lines of function foo expects an argument of type int, but received string. It's obvious what this means, I passed in a string but the signature demands an int.
So here's some relatively simple code, it is a function that evaluates a polynomial given a list of coefficients and powers:
poly :: [Int] -> [Int] -> Double -> Double
poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $ b
This produces the following compiler error output:
[1 of 1] Compiling Main ( solution.hs, solution.o )
solution.hs:11:56: error:
• Couldn't match type ‘Int’ with ‘Double’
Expected type: [Double] -> [(Double, Double)]
Actual type: [Double] -> [(Int, Double)]
• In the second argument of ‘(.)’, namely ‘zip a’
In the second argument of ‘(.)’, namely
‘map (\ (ai, bi) -> ai * (x ** bi)) . zip a’
In the expression: sum . map (\ (ai, bi) -> ai * (x ** bi)) . zip a
|
11 | poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $ b
| ^^^^^
solution.hs:11:64: error:
• Couldn't match type ‘Int’ with ‘Double’
Expected type: [Double]
Actual type: [Int]
• In the second argument of ‘($)’, namely ‘b’
In the expression:
sum . map (\ (ai, bi) -> ai * (x ** bi)) . zip a $ b
In an equation for ‘poly’:
poly a b x = sum . map (\ (ai, bi) -> ai * (x ** bi)) . zip a $ b
|
11 | poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $ b
| ^
So I already know what's wrong here. a and b are of type [Int], but I need them to be of type [Double]. However, what I don't understand is why the compiler is saying what it is:
Why is it complaining about b when a comes before it in the expression and is equally wrong?
In the top-most error, the expected type is [(Double, Double)]. Cool, makes sense. But how come the actual type is [(Int, Double)]? How did the double emerge if both a and b are [Int]?
In either case, I think what I really need is someone to walk me through how the type system eventually gets to generating these errors, so I can better understand why the error messages are what they are.
Why is it complaining about b when a comes before it in the expression and is equally wrong?
...why not? You've said yourself that they are both wrong. GHC has also figured out they are both wrong. It's telling you they are both wrong. Also, a doesn't really come "before", because there is no real concept of "before" and "after" in Haskell. If anything, it's "in-out", not "left-right", and then b (underneath only a ($)) is "before" the a (underneath zip, (.), and ($)). It doesn't matter, anyway.
In the top-most error, the expected type is [(Double, Double)]. Cool, makes sense. But how come the actual type is [(Int, Double)]? How did the double emerge if both a and b are [Int]?
sum . map _etc . zip a is expected to have type [Int] -> Double, because of the type signature and because it's the left side of a ($). Drilling deeper, zip a is supposed to be [Int] -> [(Double, Double)]. It is actually forall b. [b] -> [(Int, b)]. Using the argument type, we can choose to set b ~ Int, thereby deducing that zip a is actually [Int] -> [(Int, Int)] (which is true) where a [Double] -> [(Double, Double)] was expected, or we can choose to set b ~ Double (from the return type) and decide that, actually, zip a :: [Double] -> [(Int, Double)] (which is also true). Both ways you get an error. In fact, I think GHC is doing this in a third way, similar to the first, but I'll spare you the details.
The core of the issue is this: in a Haskell program, there are multiple ways to figure out the type of an expression if you know the types of the stuff around or in it. In a well-typed program, all these derivations agree with each other, and, in an ill-typed program, they disagree, usually in multiple ways. GHC simply chooses two of them, calls them "expected" and "actual" in a way that hopefully makes sense, and complains that they disagree. Here, you found a third derivation that is also in conflict with the "expected" derivation, but GHC, for whatever reason, chose not to use your derivation for the "actual type". Choosing which derivation to show is not easy, especially in Haskell, where everything is allowed to affect the type of everything else, though it could definitely be better. Some years ago, one of GHC's leaders did some work on much better error messages, but it appears to have link-rotted slightly—the Haskell-analyzer bridge seems to have link-rotted off the Internet.
If you're faced with an error like this, I would recommend, first of all, not writing in the _ . _ . ... $ _ style. It's easier to follow my main advice if you write that as _ $ _ $ ... $ _. I won't change it here, but you should keep that in mind.
poly :: [Int] -> [Int] -> Double -> Double
poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $ b
You see an error and it's not immediately obvious what to change. Very well, simply give up trying to decipher the hieroglyphs and replace part(s) of the RHS with _. The more of the RHS you delete, the better your chance of catching the error, going to ~95% if you erase all of it:
poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . _ $ _
-- personally, I'd nuke the scary-looking map _lambda, too,
-- but I'm also trying to keep this short
GHC will tell you that the left _ is meant to be _a -> [(Double, Double)], and the right one _a. Add the zip:
poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip _ $ _
and you'll be told you need two [Double]s, and you'll realize that using a and b didn't work because a, b :: [Int] (and GHC actually says a :: [Int]; b :: [Int] in the error message, because sometimes it isn't clear). You then figure out how to fix it:
poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip (fromIntegral <$> a) $ fromIntegral <$> b
All is well.
Why is it complaining about b when a comes before it in the expression and is equally wrong?
Well, there are two errors. It complains about zip a, and it complains about b. And it issues those errors in the order they appear in the source.
In the top-most error, the expected type is [(Double, Double)]. Cool, makes sense. But how come the actual type is [(Int, Double)]? How did the double emerge if both a and b are [Int]?
Not so fast. The actual type in that error is not [(Int, Double)]. It says that zip a is wrong, and its says the expected type is [Double] -> [(Double, Double)], while the actual type is [Double] -> [(Int, Double)]. That's not the same thing as there being an expression which is expected to be of type [(Double, Double)] and actually is of type [(Int, Double)].
zip a is a function. We know it's supposed to return [(Double, Double)] (because the rest of the composition chain processes that to return the final Double result from poly.
The remaining parameter of the function zip a needs to be of type [Double] (by the type of zip) in order for the return type to fit [(Double, Double)], and that's fine; zip a can take a [Double] argument.
The problem is that zip a is not a function of type [Double] -> [(Double, Double)]; the closest it could manage is [Double] -> [(Int, Double)], because of the use of a in the expression zip a. So that's what the error complains about.
You're asking why it doesn't complain about [(Int, Int)] instead of [(Int, Double)], since that's what you'd get if you applied zip a to b. But nowhere in your code do you do that! You apply the whole function sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a to b (via the $ operator). The type error is not complaining about zip a b being the wrong type of list, it's complaining about zip a being the wrong type of function.
It then separately complains that the second argument of the $ operator is also the wrong type to be passed as an argument to the whole function (of which zip a is a small part), but that's quite a separate issue from the other error.
What Haskell is doing during type checking is looking at every expression (including sub-expressions, at every level of nesting), and comparing:
The type the expression must have, in order to fit into its context (it calls this the "expected type")
The type the expression would have based on its components (it calls this the "actual type")
You can think of the process in this example roughly as follows:
sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $ b must result in Double, because of the type signature for poly
The first sub-expression is $ applied to sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a
$ has type (a -> b) -> a -> b (actual type)1
We know that b above must be Double by the final expected return type of poly, so $ should be something of the form (a -> Double) -> a > Double (expected type)
Expected and actual types of $ unify with no problems
Now we know the expected type of sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a is something of the form a -> Double. Lets check its actual type:
The first sub-expression in that composition chain is . applied to sum ((sum .) in operator-section notation, or (.) sum in prefix notation):
. has type (b -> c) -> (a -> b) -> a -> c; its expected type in this position is something of the form (b -> Double) -> (a -> b) -> a -> Double
sum has type (Foldable t, Num a) => t a -> a; its expected type in this position is something of the form b -> Double (needs Num Double: ✔ )
So (sum .) has type Foldable t => (a -> t Double) -> a -> Double
The next sub-expression in the composition chain is (sum .) applied to map (\(ai, bi) -> ai * (x ** bi)) . zip a
map (\(ai, bi) -> ai * (x ** bi)) . zip a is expected to fit Foldable t => a -> t Double. Lets check its actual type:
The first sub expression of that is . applied to map (\(ai, bi) -> ai * (x ** bi))
. has type (b -> c) -> (a -> b) -> a -> c; its expected type in this position is something of the form Foldable t => (b -> t Double) -> (a -> b) -> a -> t Double
So map (\(ai, bi) -> ai * (x ** bi)) is expected to fit b -> t Double
Skipping over the details, map (\(ai, bi) -> ai * (x ** bi)) actually has type [(Double, Double)] -> [Double] (because x is known to have type Double from the signature of poly).
This fits the expected type b -> t Double, and informs us that b is actually [(Double, Double)] and t is actually [] (needs Foldable []: ✔ )
So now we know that the actual type of . applied to map (\(ai, bi) -> ai * (x ** bi)) is (a -> [(Double, Double)]) -> [Double], which means the second argument of the ., which is zip a, is expected to be of the form a -> [(Double, Double)]. Lets check its actual type:
zip is of type [a] -> [b] -> [(a, b)]
a is of type [Int] from the type signature of poly
So zip a has a type like [b] -> [(Int, b)]. Trying to unify the expected and actual type forces us to instantiate b to be Double, leaving the actual type of zip a being [Double] -> [(Int, Double)]. But now there are no more type variables to instantiate. This is the first place we've found where the actual type doesn't match the expected type. So we emit a type error. In reporting the type error, we keep the fact that b was instantiated to Double, because nothing was wrong with that. So the expected type is shown as [Double] -> [(Double, Double)] and the actual type is shown as [Double] -> [(Int, Double)]
There's not much point drilling down further into zip a, because there is no meaningful expected type for the sub-components, because we don't know whether the issue we just reported was that the expected type is wrong or that the actual type was wrong (we just know that they can't be both right). We cannot say whether the problem is that zip doesn't fit [Int] -> [Double] -> [(Double, Double]), or that a doesn't fit [Double], or whether zip a is actually correct and the problem is that the context was expecting [Double] -> [(Double, Double)].
But going back out and pretending that zip a actually did fit its expected type, we establish that map (\(ai, bi) -> ai * (x ** bi)) . zip a has "actual type" [Double] -> [Double], which does unify with our expected type of Foldable t => a -> t Double
And that means that sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a has actual type [Double] -> Double, which does unify with our expected type of a -> Double (and we now know that a is Double).
Which finally allows us to get to the next top-level expression, which is (sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $) applied to b.
b is expected to have type [Double]
b actually has type [Int] (by the signature for poly)
This is our second place where actual and expected type do not match, so we report the second type error.
1 But not its actual actual type. Saying $ is simply a function with type (a -> b) -> a -> b is actually a simplification, because $ needs to support things like unlifted types, which ordinary type variables can't support. But I'm not going to get into that here. The simplification works 99% of the time.
You can see that there are a huge number of steps to follow in working out how the type system generates these errors. So I don't really find that's a helpful process to follow in trying to understand type errors.
The compiler pinpoints the exact expression its talking about: both in terms of the descent of the parse tree with all those "in the second argument of (.)" lines, and (usually more helpfully) with the graphical indication using ^^^^ characters underneath.
So step one is to think about "why would that expression be expected to have that type", looking at the surroundings. In this case it's reasonably clear why zip a should have type [Double] -> [(Double, Double)]; the result is feeding into mathematical operations that eventually produce Double, so both elements of the tuples in the list have to be Double, and the parameter of zip a must also be [Double].
Step 2 is to think about "why would that expression actually have that type". Again, that's even more obvious. If a :: [Int], then there's no way that zip a can result in something fitting _ -> [(Double, _)].
The finicky details the compiler goes through to verify everything else in the context leading up to these errors is mostly irrelevant; it effectively told you that was all fine (by not emitting any type errors there).
It's also irrelevant why it discovers zip a first and not b, or why it complains about zip a being a function that results in [(Int, Double)] instead of complaining about a being of type [Int]. Fundamentally it's just going to find a place where the expected and actual type are inconsistent, without any way to tell which one is correct (often neither of them are).
These things are understandable, and they become reasonably intuitive as you work with the compiler for longer, but these facts very rarely actually help you understand and fix the error. Just pick the first error it reports, focus on the expression it's talking about, think about why the context would cause it to have the reported "expected type", and why the sub-parts of the expression would cause it to have the reported "actual type".
Contrary to GHC's reputation for inscrutable error messages, I actually find them to be much higher quality that those I typically get when working with other languages. When you aren't familiar with them they contain a lot of information in a new format, and so they're confusing. But once you are familiar with them they are actually very good.
In fact, this particular error message is exactly along the lines of the function foo expects an argument of type int, but received string that you were expecting! It's just that the "function foo" is the . operator (which you've used twice on the same line so it identifies exactly which one it's talking about) and the argument it's expecting is another function with a complex type. The only reason it looks more complicated than the type of error message you compare it to is that it splits the expected/actual part onto two lines for readability (and points out exactly which part of those two types doesn't match!) and gives you a lot of detail about exactly which sub-expression contains the error, instead of just saying line 11: function (.) expects an argument of type [Double] -> [(Double, Double)], but received [Double] -> [(Int, Double)].
Having
poly :: [Int] -> [Int] -> Double -> Double
poly a b x = sum . map (\(ai, bi) -> ai * (x ** bi)) . zip a $ b
, on the one hand,
a :: [ Int]
zip a :: [t] -> [(Int,t)]
x :: Double
x ** bi :: Double
bi :: Double
t :: Double
zip a :: [Double] -> [(Int, Double)] derived
, but on the other,
poly a b x :: Double
sum :: [Double] -> Double
ai * (x ** bi) :: Double
(ai , bi) :: (Double, Double)
zip a :: [Double] -> [(Double, Double)] expected

Converting types in Haskell

I'm working on a conversion problem for homework, and am a complete Haskell newbie, so bear with me. On one of them, it asks us to attempt to get the type of a function to be:
fc :: (Bool, [Char]) -> Int -> Integer -> [Bool]
Without worrying about what the actual function does or anything. These functions will not be run, it is just a test to see if we can convert types correctly. So far the furthest I can get is this:
fc :: (Bool, [Char]) -> Int
fc (x, y) = ord (head y)
Where I am turning it into an Int. When I try to turn it into an Integer using the toInteger function, it gives me:
Couldn't match expected type `Int -> Integer'
with actual type `Integer'
In the return type of a call of `toInteger'
Probable cause: `toInteger' is applied to too many arguments
In the expression: toInteger (ord (head y))
Any tips for the new guy?
Edit:
What I have been trying, for reference, is:
fc :: (Bool, [Char]) -> Int -> Integer
fc (x, y) = toInteger (ord (head y))
And I am getting the error above.
Your type signature is wrong. If you convert something you can't write it into the type signature. Only the last one is the return type. The others are parameter types.
Follow these:
fc::(Bool,[Char])->Integer
fc (x,y) = toInteger . ord . head $ y
fc::(Bool,[Char])->Int->Integer--
fc (x,y) n = if n == w then n else w
where w = toInteger . ord . head $ y
Edit:
The others mentioned currying what is absolutely correct if your teacher expect it. But the conversions doesn't take place in the type sign.
As n.m. says, the idea this is getting at is called currying. Basically, in Haskell, any function takes a single value and returns a single value: a -> b.
So, given this restriction, how can we implement functions like addition, which need two parameters? The answer is that we implement a function which takes a number, and returns another function which takes a number and returns a number. Laying it out this way might clarify things:
add :: Int -> Int -> Int
add x = f where f y = x + y
(which is equivalent to add x y = x + y, as well as add = (+)).
In your case, you should read the error carefully: Couldn't match expected type Int -> Integer with actual type Integer In the return type of a call of toInteger means that Haskell is expecting fc to return a value of type Int -> Integer, because that's what your type signature says, but the definition you've provided will always produce a value of type Integer.

Haskell Map function implementation issues

I just began to learn Haskell and am having trouble with adjusting to the language, for example on the implementation of map more specifically when trying to do similar operations as in the example bellow;
rotate :: Dimensions -> imgBlock -> [(imgBlock,Int)]
rotate d ((p, pix), s, t)
= zip [((p, f pix), s, t) | f <- transformate (fst d)] [0..7]
makeAllRotations :: Dimensions -> [imgBlock] -> [(imgBlock,Int)]
makeAllRotations d ib = map concat (rotate d ib) //Error points Here
Where
type imgBlock = (Block, Int, Int)
type Block = (Pnt, Pxl)
type Dimensions = (Int, Int)
And this is one of the errors i get
asdf.hs:73:30:
Couldn't match expected type `(imgBlock, Int)'
with actual type `[a0]'
Expected type: [[a0]] -> (imgBlock, Int)
Actual type: [[a0]] -> [a0]
In the first argument of `map', namely `concat'
In the expression: map concat (rotate d ib)
I find myself quite frustrated trying to adjust to this new programming 'paradigm' where most of the things I managed to do are through trial and error. I am obviously not understanding map correctly, although i have read the documentation on this website, but all the examples are shown in console like map (2+) [1,2,3] not so much when using them in functions.
Could I get some pointers on where am i going wrong on my map implementation. Thks
The best way to find the problem is to look at the types:
rotate :: Dimensions -> ImgBlock -> [(ImgBlock,Int)]
makeAllRotations :: Dimensions -> [ImgBlock] -> [(ImgBlock,Int)]
map :: (a -> b) -> [a] -> [b]
concat :: [[a]] -> [a]
The map function is trying to call concat on each of the (ImgBlock,Int) pairs in the list returned by rotate. But concat expects to get a nested list as its argument. But the big thing that helped me figure out how to fix it was looking at rotate d ib. The second argument to rotate is ImgBlock, but in that context ib :: [ImgBlock]. You can't pass in a list when a single item is expected. But that's what the map function is for. It allows you to take a function that accepts a single item ('a' in the type signature above) and use that function when you have [a]. I suspect what you want is something like this:
makeAllRotations d ib = concat $ map (rotate d) ib
Because rotate returns a list, map (rotate d) ib returns a list of lists, which fits perfectly as the first argument to the concat function.

What to do with “Inferred type is less polymorphic than expected”?

I need the Numeric.FAD library, albeit still being completely puzzled by existential types.
This is the code:
error_diffs :: [Double] -> NetworkState [(Int, Int, Double)]
error_diffs desired_outputs = do diff_error <- (diff_op $ error' $ map FAD.lift desired_outputs)::(NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double))
weights <- link_weights
let diffs = FAD.grad (diff_error::([FAD.Dual tag a] -> FAD.Dual tag b)) weights
links <- link_list
return $ zipWith (\link diff ->
(linkFrom link, linkTo link, diff)
) links diffs
error' runs in a Reader monad, ran by diff_op, which in turn generates an anonymous function to take the current NetworkState and the differential inputs from FAD.grad and stuffs them into the Reader.
Haskell confuses me with the following:
Inferred type is less polymorphic than expected
Quantified type variable `tag' is mentioned in the environment:
diff_error :: [FAD.Dual tag Double] -> FAD.Dual tag Double
(bound at Operations.hs:100:33)
In the first argument of `FAD.grad', namely
`(diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b)'
In the expression:
FAD.grad (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights
In the definition of `diffs':
diffs = FAD.grad
(diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights
this code gives the same error as you get:
test :: Int
test =
(res :: Num a => a)
where
res = 5
The compiler figured that res is always of type Int and is bothered that for some reason you think res is polymorphic.
this code, however, works fine:
test :: Int
test =
res
where
res :: Num a => a
res = 5
here too, res is defined as polymorphic but only ever used as Int. the compiler is only bothered when you type nested expressions this way. in this case res could be reused and maybe one of those uses will not use it as Int, in contrast to when you type a nested expression, which cannot be reused by itself.
If I write,
bigNumber :: (Num a) => a
bigNumber = product [1..100]
then when bigNumber :: Int is evaluated,
it's evaluating (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)],
and when bigNumber :: Integer is evaluated,
it's evaluating (product :: [Integer] -> Integer) [(1 :: Integer) .. (100 :: Integer)].
Nothing is shared between the two.
error_diffs has a single type, that is: [Double] -> NetworkState [(Int, Int, Double)]. It must evaluate in exactly one way.
However, what you have inside:
... :: NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double)
can be evaluated in different ways, depending on what tag is.
See the problem?

Resources