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

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?

Related

How can I find the definition of a Prelude function?

I'm currently trying to find the definition of the words function to help get an idea for a similar function I'm writing. So I was wondering is there somewhere that has all the definitions of the Prelude functions? Maybe a GHCi command to show the definition of one, or something on the Haskell wiki, I'm not sure.
Or if there isn't somewhere I can find that do any of y'all know what the definitions of words is?
Most packages on Hackage come with documentation that also includes a link to the source code for every function. You can usually find the function via Hoogle.
In the case of words, the Prelude documentation is found here, and the source is found at https://hackage.haskell.org/package/base-4.16.3.0/docs/src/Data.OldList.html#words:
-- | 'words' breaks a string up into a list of words, which were delimited
-- by white space.
--
-- >>> words "Lorem ipsum\ndolor"
-- ["Lorem","ipsum","dolor"]
words :: String -> [String]
{-# NOINLINE [1] words #-}
words s = case dropWhile {-partain:Char.-}isSpace s of
"" -> []
s' -> w : words s''
where (w, s'') =
break {-partain:Char.-}isSpace s'
This should in general also work with local documentation.
For ghci specifically, there are :info and :list commands, but :list words only produces an error message ("cannot list source code for words: module base-…:Data.OldList is not interpreted") for me.
Documentation of a function.
To search for the definition, look at hackage. In the case of words: https://hackage.haskell.org/package/base-4.16.3.0/docs/Prelude.html#v:words
Finding a function
To find a function, use hoogle. It is the de-facto tool for finding a function.
Example:
This is inside the shell. Hoogle can be installed at the samne time as when ghc is.
Find a function like so:
> hoogle "subtract"
Prelude subtract :: Num a => a -> a -> a
GHC.Num subtract :: Num a => a -> a -> a
Distribution.Compat.Prelude.Internal subtract :: Num a => a -> a -> a
GHC.Prelude subtract :: Num a => a -> a -> a
Hedgehog.Internal.Prelude subtract :: Num a => a -> a -> a
BasePrelude subtract :: Num a => a -> a -> a
RIO.Prelude subtract :: Num a => a -> a -> a
System.Metrics.Gauge subtract :: Gauge -> Int64 -> IO ()
ClassyPrelude subtract :: Num a => a -> a -> a
Algebra.Additive subtract :: C a => a -> a -> a
-- plus more results not shown, pass --count=20 to see more
The cool thing is, you can also search for types and functions with certain types. For example, here is the list of functions which will take an Int and return an Int.
hoogle "Int -> Int"
GHC.Unicode wgencat :: Int -> Int
System.Win32.DebugApi dr :: Int -> Int
Codec.Picture.Jpg.Internal.Common toBlockSize :: Int -> Int
Statistics.Function nextHighestPowerOfTwo :: Int -> Int
Numeric.SpecFunctions log2 :: Int -> Int
Math.NumberTheory.Logarithms intLog2 :: Int -> Int
Math.NumberTheory.Logarithms intLog2' :: Int -> Int
Streamly.Internal.Data.Array.Foreign.Mut.Type roundUpToPower2 :: Int -> Int
Streamly.Internal.System.IO arrayPayloadSize :: Int -> Int
Data.Array.Comfort.Shape triangleSize :: Int -> Int
-- plus more results not shown, pass --count=20 to see more

Syntax in Functions (Expected kind `* -> Constraint', but `Int' has kind `*') [duplicate]

This question already has answers here:
`String' is applied to too many type arguments
(2 answers)
Closed 2 years ago.
I'm starting to learn Haskell and I'm struggling with syntax in Functions. I'm trying to create a function that receives a Number 'e' and a Number 'n', returning a list with of 'n' times 'e'.
Example: repn 3 5 would return [3,3,3,3,3]:
repn :: Int a => a -> a -> [a]
repn e n
| n >= 1 = (take n (repeat e))
| otherwise = []
But I'm getting this error:
* Expected kind `* -> Constraint', but `Int' has kind `*'
* In the type signature: replica :: Int a => a -> a
As a rule of thumb, writing something of the form Foo a => ... only makes sense of Foo is a type class. Unlike in OO languages, a class and a type in Haskell are completely different things. Int is a type, therefore it cannot be used in this way; instead you should simply use
repn :: Int -> Int -> [Int]
...though actually there's no reason to restrict the list-element type at all, the signature could as well be
repn :: a -> Int -> [a]
Alternatively, you can use a type class: the class of “int-like types” is Integral. Then you can't use take directly, as that is restricted to Int for the counter argument; however you can convert any integral type to Int:
repn :: Integral n => a -> n -> [a]
repn e n = take (fromIntegral n) $ repeat e
-- Note no case distinction is needed, because `take` already yields
-- an empty list if `n<1`.
Your type definition is not correct. The double arrow is used to show required typeclasses (aka kind * -> Constraint), or a constraint on types. However, Int is itself a type (aka kind *).
You can't specify types in this way. In your implementation, n must be an Int, but e could be anything. Since you specify that it should be a number, though, you can constrain it with the Num typeclass. The correct version of your signature therefore is:
repn :: Num a => a -> Int -> [a]
If you want e to be constrained to an Int, then your signature should be
repn :: Int -> Int -> [Int]
If you don't need any constraints on e, your signature can be
repn :: a -> Int -> [a]
These are all valid type signatures for the function you have written. (Though in actual code, I would just point you to the builtin replicate function.)

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

How to define a function returning a polymorphic value

I expect the function noToState below works, which travels among all states to find the one which matches the given state number and return the state.
class State a where
allStates :: [a]
class (State a) => IntState a where
-- starting from zero, consecutive
stateNo :: a -> Integer
noToState :: (IntState a) => Integer -> a
noToState n = case lookup n $ zip (map stateNo allStates) allStates of
Just st -> st
Nothing -> undefined -- this should never happen
However, it yields an error: Could not deduce (IntState a0) arising from a use of ‘stateNo’.
So in the code where did I make the mistakes? How should I fix them? Thanks.
Change it to something like this:
noToState :: (IntState a) => Integer -> a
noToState n = case lookup n $ zip (map stateNo allSts) allSts of
Just st -> st
Nothing -> undefined -- this should never happen
where allSts = allStates
The problem is that you use allStates twice and it could be different things

How to declare function (type misunderstanding Maybe)

I need a function which works like:
some :: (Int, Maybe Int) -> Int
some a b
| b == Nothing = 0
| otherwise = a + b
Use cases:
some (2,Just 1)
some (3,Nothing)
map some [(2, Just 1), (3,Nothing)]
But my code raise the error:
The equation(s) for `some' have two arguments,
but its type `(Int, Maybe Int) -> Int' has only one
I don't understand it.
Thanks in advance.
When you write
foo x y = ...
That is notation for a curried function, with a type like:
foo :: a -> b -> c
You have declared your function to expect a tuple, so you must write it:
some :: (Int, Maybe Int) -> Int
some (x, y) = ...
But Haskell convention is usually to take arguments in the former curried form. Seeing funcitons take tuples as arguments is very rare.
For the other part of your question, you probably want to express it with pattern matching. You could say:
foo :: Maybe Int -> Int
foo Nothing = 0
foo (Just x) = x + 1
Generalizing that to the OP's question is left as an exercise for the reader.
Your error doesn't come from a misunderstanding of Maybe: The type signature of some indicates that it takes a pair (Int, Maybe Int), while in your definition you provide it two arguments. The definition should thus begin with some (a,b) to match the type signature.
One way to fix the problem (which is also a bit more idiomatic and uses pattern matching) is:
some :: (Int, Maybe Int) -> Int
some (a, Nothing) = a
some (a, Just b) = a + b
It's also worth noting that unless you have a really good reason for using a tuple as input, you should probably not do so. If your signature were instead some :: Int -> Maybe Int -> Int, you'd have a function of two arguments, which can be curried. Then you'd write something like
some :: Int -> Maybe Int -> Int
some a Nothing = a
some a (Just b) = a + b
Also, you might want to add the following immediate generalization: All Num types are additive, so you might aswell do
some :: (Num n) => n -> Maybe n -> n
some a Nothing = a
some a (Just b) = a + b
(I've violated the common practice of using a, b, c... for type variables so as not to confuse the OP since he binds a and b to the arguments of some).

Resources