Haskell - Cannot infer instance - haskell

I have written the following predicate (Lines 94-99)
diffFreqMatrix :: Fractional a => [[Rating a]] -> [a]
diffFreqMatrix (x:xs) = diffFreqMatrixH (x:xs) (matrixPairs (length x))
diffFreqMatrixH _ [] = []
diffFreqMatrixH x ((a,b):ys) = [(diffFreqMatrixH2 x a b 0 0)] ++ diffFreqMatrixH x ys
diffFreqMatrixH2 [] _ _ x y = x / y
diffFreqMatrixH2 (x:xs) a b summ num = if (((x!!a) /= NoRating) && ((x!!b) /= NoRating)) then diffFreqMatrixH2 xs a b (summ + ((x!!a) - (x!!b))) (num + 1) else diffFreqMatrixH2 xs a b summ num
supposedly it calculates an average I want but i'm getting this error
ERROR file:.\project.hs:98 - Cannot infer instance
*** Instance : Fractional (Rating a)
*** Expression : diffFreqMatrixH2
Helpers im using in case u want to take a look
matrixPairs :: Num a => a -> [(a,a)]
matrixPairs 0 = []
matrixPairs c = matrixPairsH 0 0 (c-1)
matrixPairsH a b c = [(a,b)] ++ if ((b == c) && (a == c)) then [] else if (b == c) then (if (a==c) then [] else matrixPairsH (a+1) 0 c ) else matrixPairsH a (b+1) c
differeneRatings :: Fractional a => Rating a -> Rating a -> a
differeneRatings NoRating (R a) = 0
differeneRatings (R a) NoRating = 0
differeneRatings NoRating NoRating = 0
differeneRatings (R a) (R b) = a - b

You use Rating as as if they were just numbers here:
(x!!a) - (x!!b)
You presumably need to use case or similar to pattern match on x!!a and x!!b to extract the number they contain. You can move the check for NoRating into that case match to simplify your code. For example:
case (x!!a, x!!b) of
(YesRating ra, YesRating rb) -> diffFreqMatrixH2 xs a b (summ + ra - rb) (num + 1)
_ -> diffFreqMatrixH2 xs a b summ num
Once you get this working the way you want, I encourage you to post to the code review StackExchange; your code can be cleaned up significantly to be both simpler and faster.

Related

Why won't this case of syntax compile properly?

Very new to Haskell here. I'm not sure why this piece of case of syntax won't compile properly:
-- | Use column headers to determine offsets for each row in a table
splitHeader :: Alignment -> String -> [(String,Int)]
splitHeader a h = case a of
AlignLeft -> reverse ((foldr f b h) ("", 0) [] 2)
AlignRight -> reverse ((foldl f b h) ("", 0) [] 2)
where b (n', w') l' m' = (reverse n', w'):l'
f c b (n, w) l m
| m == 2 && c == ' ' = b (n, w+1) l 0
| m == 2 && c /= ' ' = b (c:n, w+1) l 1
| m == 1 && c == ' ' = b (n, w+1) l 0
| m == 1 && c /= ' ' = b (c:n, w+1) l 1
| m == 0 && c == ' ' = b (n, w+1) l 0
| m == 0 && c /= ' ' = b ([c], 1) ((reverse n, w):l) 1
Compile error:
Kata.hs:50:43: warning: [-Wdeferred-type-errors]
• Couldn't match type ‘([Char], Int)
-> [([Char], Int)] -> Integer -> [([Char], Int)]’
with ‘Char’
Expected type: (([Char], Int)
-> [([Char], Int)] -> Integer -> [([Char], Int)])
-> (([Char], Int) -> [([Char], Int)] -> Integer -> [([Char], Int)])
-> ([Char], Int)
-> [([Char], Int)]
-> Integer
-> [([Char], Int)]
Actual type: Char
-> (([Char], Int) -> [([Char], Int)] -> Integer -> [([Char], Int)])
-> ([Char], Int)
-> [([Char], Int)]
-> Integer
-> [([Char], Int)]
• In the first argument of ‘foldl’, namely ‘f’
In the first argument of ‘reverse’, namely
‘((foldl f b h) ("", 0) [] 2)’
In the expression: reverse ((foldl f b h) ("", 0) [] 2)
|
50 | AlignRight -> reverse ((foldl f b h) ("", 0) [] 2)
| ^
Kata.hs:50:47: warning: [-Wdeferred-type-errors]
• Couldn't match type ‘Char’
with ‘([Char], Int)
-> [([Char], Int)] -> Integer -> [([Char], Int)]’
Expected type: [([Char], Int)
-> [([Char], Int)] -> Integer -> [([Char], Int)]]
Actual type: String
• In the third argument of ‘foldl’, namely ‘h’
In the first argument of ‘reverse’, namely
‘((foldl f b h) ("", 0) [] 2)’
In the expression: reverse ((foldl f b h) ("", 0) [] 2)
|
50 | AlignRight -> reverse ((foldl f b h) ("", 0) [] 2)
| ^
Ok, one module loaded.
The types of foldr and foldl are slightly different:
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b
But you are passing the same function f to both.
If you replace the argument f with flip f the types work out:
splitHeader :: Alignment -> String -> [(String,Int)]
splitHeader a h = case a of
AlignLeft -> reverse ((foldr f b h) ("", 0) [] 2)
AlignRight -> reverse ((foldl (flip f) b h) ("", 0) [] 2)
where b (n', w') l' m' = (reverse n', w'):l'
f c b (n, w) l m
| m == 2 && c == ' ' = b (n, w+1) l 0
| m == 2 && c /= ' ' = b (c:n, w+1) l 1
| m == 1 && c == ' ' = b (n, w+1) l 0
| m == 1 && c /= ' ' = b (c:n, w+1) l 1
| m == 0 && c == ' ' = b (n, w+1) l 0
| m == 0 && c /= ' ' = b ([c], 1) ((reverse n, w):l) 1

Recursion through Nat-kinds

This question is a sequel to the following question. Refer to it first:
Overlapping instances via Nat-kind
Now it's time to make the instance of Group Symmetric. After some savage math, I've come up to an instance that works in principle, but actually doesn't:
sIndex :: forall n. KnownNat n => Symmetric n -> Integer -> Integer
sIndex xs m = sIndex_ xs (m `mod` n)
where
n = toInteger (natVal (Proxy :: Proxy n))
sIndex_ :: Symmetric m -> Integer -> Integer
sIndex_ S1 _ = 0
sIndex_ (x :. _) 0 = cIndex x
sIndex_ (x :. xs) m = let
i = cIndex x + sIndex_ xs (m-1)
in if i < n then i else i - n
instance KnownNat n => Semigroup (Symmetric n) where
x <> y = go [] n where
n = toInteger (natVal (Proxy :: Proxy n))
go :: forall m. [(Integer,Integer)] -> Integer -> Symmetric m
go j m
| 0 == m = S1
| otherwise = let
i = sIndex y (sIndex x (n-m))
ix = foldr f i j
in cyclic ix :. go ((ix,m) :j) (m-1)
f (j,m) i = (i - j) `mod` m - 1
The go function inside the Semigroup instance should build the result by having recursion though Symmetric n, Symmetric (n-1), and so on until Symmetric 1. But GHC doesn't know how to do it and outputs the following error message:
Group_Symmetric.hs:89:24: error:
• Couldn't match type ‘m’ with ‘1’
‘m’ is a rigid type variable bound by
the type signature for:
go :: forall (m :: Nat).
[(Integer, Integer)] -> Integer -> Symmetric m
at Group_Symmetric.hs:87:9-69
Expected type: Symmetric m
Actual type: Symmetric 1
So what would the workaround be? Is it possible for go to be able to return any instantation of Symmetric m (m from 1 to n)?
A slight change of go and f solved the problem:
instance KnownNat n => Semigroup (Symmetric n) where
x <> y = go y [] n where
n = toInteger (natVal (Proxy :: Proxy n))
go :: forall m. Symmetric m -> [(Integer,Integer)] -> Integer -> Symmetric m
go S1 _ _ = S1
go (_ :. xs) j m = let
i = sIndex y (sIndex x (n-m))
ix = foldr f i j
in Cyclic ix :. go xs ((ix,m) :j) (m-1)
f (j,m) i = let
ix = (i - j) `mod` m - 1
in if 0 <= ix then ix else ix + m
The key idea is to introduce a dummy parameter. Also note that Cyclic was used instead of cyclic.
Unfortunately, it turns out that I did some math wrong. It is to be corrected.
EDIT: Here is the corrected sIndex, which completes the instance:
sIndex :: forall n. KnownNat n => Symmetric n -> Integer -> Integer
sIndex xs m = let
n = toInteger (natVal (Proxy :: Proxy n))
in sIndex_ xs (m `mod` n) n
where
sIndex_ :: Symmetric m -> Integer -> Integer -> Integer
sIndex_ S1 _ _ = 0
sIndex_ (x :. _) 0 _ = cIndex x
sIndex_ (x :. xs) m n = let
i = cIndex x + sIndex_ xs (m-1) (n-1) + 1
in if n <= i then i - n else i

Haskell - Form a matrix based on a list Matrix

I would to make a haskell function that takes a list of Item Ratings(a data type I declared), looking like this:
[[NoRating,R 5.0],[R 5.0,R 4.0],[R 3.0,R 1.0]]
the declaration of Rating looks like this:
data Rating c = NoRating | R c deriving (Show, Eq)
in the list each sublist represents ratings belonging to a user, each sublist contains multiple items, in the previous example 2 items were in the sublist,
What I would like to return is a list of item rating differences from a matrix like input, The value at row i and column j represents the sum of the differences between the ratings given to item i and item j by the same user
for example, for the input
dMatrix [[NoRating,R 5.0],[R 5.0,R 4.0],[R 3.0,R 1.0]]
I would like to return
[0.0,3.0,-3.0,0.0]
I have already implemented a difference function that takes 2 ratings and returns the difference, it looks like this, would be nice to use it through
differenceRatings :: Fractional a => Rating a -> Rating a -> a
differenceRatings NoRating (R a) = 0
differenceRatings (R a) NoRating = 0
differenceRatings (R a) (R b) = a - b
I'm having a hard time implementing this because the only way I know to loop in haskell is recursion but in this instance I need to do in a specific matrix order and access multiple sublist items of same index at same time, thanks for your help.
Picture as like example, first we do column 0 with column 0, difference is 0,
then we do column 0 with column 1, rating of item 0 for user 1 - item 2 for user 1, and so on for user 2 and 3 then sum them, put that in the second index of result list
then we do column 1 with column 0, negative of what is before generally
lastly column 1 with column 1, difference is 0
I have drafted this code and tried it but am getting a type error
dMatrix :: Fractional a => [[Rating a]] -> [a]
dMatrix [] = []
dMatrix x = dMatrixH1 x 0 0
dMatrixH1 (x:xs) i j = (dMatrixH x:xs i j) ++ (if (j < ((length (x:xs))-1))
then dMatrixH (x:xs) i (j+1) else if (i < ((length xs)-1)) then dMatrixH
(x:xs) (i+1) 0 else 0)
dMatrixH [] _ _ = 0
dMatrixH (x:xs) i j = (differeneRatings (x!!i) (x!!j)) + dMatrixH xs i j
Managed to do it using 2 of my helper functions, posting them first
matrixPairs :: Num a => a -> [(a,a)]
matrixPairs 0 = []
matrixPairs c = matrixPairsH 0 0 (c-1)
matrixPairsH a b c = [(a,b)] ++ if ((b == c) && (a == c)) then [] else if (b == c) then (if (a==c) then [] else matrixPairsH (a+1) 0 c ) else matrixPairsH a (b+1) c
and
differeneRatings :: Fractional a => Rating a -> Rating a -> a
differeneRatings NoRating (R a) = 0
differeneRatings (R a) NoRating = 0
differeneRatings NoRating NoRating = 0
differeneRatings (R a) (R b) = a - b
and here's the code for the required function
dMatrix :: Fractional a => [[Rating a]] -> [a]
dMatrix [] = []
dMatrix (x:xs) = dMatrixH (x:xs) (matrixPairs (length x))
dMatrixH _ [] = []
dMatrixH x ((a,b):ys) = [(dMatrixH2 x a b)] ++ dMatrixH x ys
dMatrixH2 [] _ _ = 0
dMatrixH2 (x:xs) a b = (differeneRatings (x!!a) (x!!b)) + dMatrixH2 xs a b

Haskell: using (fromInteger (a `div` b) / 1 == a / b) as guard?

I'm new to Haskell and i don't understand why my guard won't accept it. here's my code. The guard should fire in case b is a divider of a.
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = f p n
| otherwise = f n p
where
f :: Integer -> Integer -> Integer;
f a b
| (fromInteger (a `div` b) / 1 == a / b) = b
| otherwise = f a (b - 1)
Here's the error shown.
testscript.hs:168:28: error:
• No instance for (Fractional Integer) arising from a use of ‘/’
• In the first argument of ‘(==)’, namely
‘fromInteger (a `div` b) / 1’
In the expression: (fromInteger (a `div` b) / 1 == a / b)
In a stmt of a pattern guard for
an equation for ‘f’:
(fromInteger (a `div` b) / 1 == a / b)
|
168 | | (fromInteger (a `div` b) / 1 == a / b) = b | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
I think you make it the function more complex that necessary. Converting numbers between the Integer and Floating world can be dangerous, since it introduces rounding problems.
If I understand it correctly, you want to check if a is dividable by b. You can check this by verifying that mod a b == 0, and we are still in the integer worlds. So we can rewrite the program to:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| p > n = f p n
| otherwise = f n p
where f a b | mod a b == 0 = b
| otherwise = f a (b-1)
Since a does not change in the recursive calls, we can factor that out:
gCF :: Integer -> Integer -> Integer
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
We can also generalize the signature to let it work with any Integral type:
gCF :: Integral i => i -> i -> i
gCF n p | p <= 0 || n <= 0 = error "Input should be positive"
| otherwise = f (min p n)
where a = max p n
f b | mod a b == 0 = b
| otherwise = f (b-1)
i found a solution!
gCF :: Integer -> Integer -> Integer;
gCF n p
| (p <= 0 || n <= 0) = error "Input should be positive"
| (p > n) = floor (f (fromInteger p) (fromInteger n) (fromInteger n))
| otherwise = floor (f (fromInteger n) (fromInteger p) (fromInteger p))
where
f :: Float -> Float -> Float -> Float;
f a b c
| (fromInteger (floor (a / c)) == a / c) && (fromInteger (floor (b / c)) == b / c) = c
| otherwise = f a b (c - 1)

Implementing Wiener's Algorithm in Haskell - No instance for (RealFrac a0) arising from a use of `wiener'

I'm trying to implement in Haskell the Wiener's Algorithm from the book Cryptography: Theory and Practice, Third Edition. Here's what I've written so far:
import Data.List
wiener e n = factors
where euclid = euclidean e n
cs = 1 : head euclid : rest cs euclid
ds = 0 : 1 : rest ds euclid
ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
qs = map (\x -> quad 1 (x - n - 1) n) ns
factors = find (\(p, q) -> isInt p && 0 < p && p < n
&& isInt q && 0 < q && q < n) qs
rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))
euclidean _ 0 = []
euclidean a b = a `div` b : euclidean b (a `mod` b)
quad a b c
| d > 0 = ((-b + sqrt d) / (2 * a), (-b - sqrt d) / (2 * a))
| otherwise = (0.0, 0.0)
where d = b * b - 4 * a * c
isInt x = x == fromInteger (round x)
Trying wiener 238123333 293719721 gives me:
No instance for (RealFrac a0) arising from a use of `wiener'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
No instance for (Num a0) arising from the literal `238123333'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s
How should I proceed? Is there any general number type such that it can be used everywhere?
I tracked down the error. The return type of euclidean is Integral a => [a] while quad returns an instance of RealFrac. Since you use the value n and e as arguments to both functions, n and e must be instances of both typeclasses.
wiener :: (Floating b, Integral a, RealFrac b) => a -> a -> Maybe (b,b)
wiener e' n' = factors
where euclid = map fromIntegral $ euclidean e' n' -- convert result from `Integral` to `Num`
e = fromIntegral e' -- convert Integral to Num
n = fromIntegral n'
cs = 1 : head euclid : rest cs euclid
ds = 0 : 1 : rest ds euclid
ns = filter isInt $ drop 2 $ zipWith (\x y -> (x * e - 1) / y) ds cs
qs = map (\x -> quad 1 (x - n - 1) n) ns
factors = find (\(p, q) -> isInt p && 0 < p && p < n
&& isInt q && 0 < q && q < n) qs
rest xs ys = zipWith (+) xs (zipWith (*) (tail ys) (tail xs))

Resources