Haskell error message Expecting one more argument - haskell

Im trying to solve this kind of equatin: e^x + sqrt(x) = d, when d is known. It does not have analytic solution so I use variation of binary search to solve it:
helper x = exp x + sqrt x
ex2 c0 c1 x
| abs (h0 - h1) < 10 ^^ (-6) = c0
| hm < x = ex2 m c1 x
| hm >= x = ex2 c0 m x
where h0 = helper c0
h1 = helper c1
m = c0 + (c1 - c0)/2
hm = helper m
This works fine from ghci (c0 and c1 is min and max value for search) but i have problems reading argument x from stdio:
main = do
seed <- getLine
let output = show ex2 0 6 (read seed :: Floating) -- Result is somewhere between helper(0) and helper(6)
in putStrLn output
This breaks my code. It does not compile or load in ghci. I got this error message:
ex2.hs:14:46:
Expecting one more argument to ‘Floating’
Expected a type, but ‘Floating’ has kind ‘* -> Constraint’
In an expression type signature: Floating
In the fourth argument of ‘show’, namely ‘(read seed :: Floating)’
In the expression: show ex2 0 6 (read seed :: Floating)
Can someone explain what it means and how to fix my main function?

There was parentheses missing in let.. line:
Another error: show (ex2 ... (read seed :: Double)) requires parentheses. – chi

Related

Function that tells if a number ir prime or not

``
I'm a Haskell newbie and I'm defining a function that given an Int n it tells if a number is prime or not by searching for an 2<=m<=sqrt(n) that mod n m ==0
if such m exists, then n is not prime, if not then n is prime.
I'm trying to define a list with numbers m between 2 and sqrt n, that mod n m ==0
My thought is that if the list is empty then n is prime, it not, n is not prime
`
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
l = [x|x<-[2.. sqrt n], mod n x == 0]
`
But there seems to be a problem with sqrt n when I run my code and I can't understand it. can someone explain what I'm doing wrong/what to change for my code to run/ and why there's an error?
Running the code gives the following error
test.hs:9:28: error:
• No instance for (Floating Int) arising from a use of ‘sqrt’
• In the expression: sqrt n
In the expression: [2 .. sqrt n]
In a stmt of a list comprehension: x <- [2 .. sqrt n]
|
9 | l = [x|x<-[2.. sqrt n], mod n x == 0]
| ^^^^^^
You are correct in saying that the error is with sqrt, but the rest is pretty opaque to a new Haskell developer. Lets try by checking the type of sqrt to see if that helps.
Prelude> :t sqrt
sqrt :: Floating a => a -> a
Here I'm using ghci to interactively write code. :t asks for the type of the preceeding expression. The line sqrt :: Floating a => a -> a says sqrt takes in some floating point number a and returns something of the same type.
Similar to our error message we see this Floating thing. this thing is a typeclass but for the sake of solving this problem we'll save understanding those for later. In essence, haskell is trying to tell you that Int is not floating point number which is what sqrt expects. We can amend that by turning our Int into a Float with fromIntegral which is a really general function for turning number types into one another. (see Get sqrt from Int in Haskell)
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float -- new! - tell fromIntegral we want a float
asFloat = fromIntegral n -- new! turn n into a Float
l = [x|x<-[2..sqrt asFloat], mod n x == 0]
This also errors! but it's a new one!
test.hs:10:48: error:
• Couldn't match expected type ‘Int’ with actual type ‘Float’
• In the second argument of ‘mod’, namely ‘x’
In the first argument of ‘(==)’, namely ‘mod n x’
In the expression: mod n x == 0
|
10 | l = [x|x<-[2..sqrt asFloat], mod n x == 0]
| ^
this is saying that x is suddenly a Float. When we changed to [2..sqrt asFloat] we now have made a list of Floats ([Float]). We need to change that back to [Int]. we can do that by calling floor on the result of the square root.
isprime' :: Int -> Bool
isprime' n | l == [] = True
| otherwise = False
where
asFloat :: Float
asFloat = fromIntegral n
l = [x|x<-[2..floor (sqrt asFloat)], mod n x == 0] -- new! I added floor here to change the result of sqrt from a `Float` into a `Int`
This now correctly compiles.

Haskell: How to define Binary instance for (BigFloat e)?

How do i define a Binary instance for Data.Number.BigFloat?
I've defined an instance for LongDouble by writing:
instance Binary LongDouble where
put d = put (decodeFloat d)
get = do
x <- get
y <- get
return $! encodeFloat x y
However trying the following doesn't work:
instance Binary (BigFloat e) where
put d = put (decodeFloat d )
get = do
x <- get
y <- get
return $! encodeFloat x y
GHC gives this error message:
/home/usr/Documents/src/Lib.hs:27:18: error:
• No instance for (Epsilon e) arising from a use of ‘decodeFloat’
Possible fix:
add (Epsilon e) to the context of the instance declaration
• In the first argument of ‘put’, namely ‘(decodeFloat d)’
In the expression: put (decodeFloat d)
In an equation for ‘put’: put d = put (decodeFloat d)
|
27 | put d = put (decodeFloat d )
| ^^^^^^^^^^^^^
/home/usr/Documents/src/Lib.hs:31:19: error:
• No instance for (Epsilon e) arising from a use of ‘encodeFloat’
Possible fix:
add (Epsilon e) to the context of the instance declaration
• In the second argument of ‘($!)’, namely ‘encodeFloat x y’
In a stmt of a 'do' block: return $! encodeFloat x y
In the expression:
do x <- get
y <- get
return $! encodeFloat x y
|
31 | return $! encodeFloat x y
If I provide a specific type for e, such as Prec500, i get this message :
• Illegal instance declaration for ‘Binary (BigFloat Prec500)’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘Binary (BigFloat Prec500)’
And using FlexibleInstances compiles, but doesn't result in correctly encoded numbers.
The following also compiles but doesn't encode correctly either:
instance Epsilon e => Binary (BigFloat e) where
put d = put (decodeFloat d )
get = do
x <- get
y <- get
return $! encodeFloat x y
This BigFloat seems to be not super-well-done. The problem lies here:
> floatDigits (0 :: BigFloat Prec500)
-9223372036854775808
(The correct answer should be 500.) I admit I don't fully understand why that is happening; but from the source, the way floatDigits is computed is by taking the log of the precision -- but log is a thing that happens on Doubles and Double doesn't have enough precision to represent 1e-500. So that method of computing the digit count seems doomed from the start.
Why do I say I don't fully understand? Well, I see the following in the source:
floatDigits (BF m _) =
floor $ logBase base $ recip $ fromRational $ precision m
From my reading, fromRational should produce 0 :: Double. But if that were true, the final value would be 0, not minBound:
> floor $ logBase 10 $ recip $ (0 :: Double) :: Int
0
So perhaps there is some dodgy rewriting going on or something.
Anyway, a proper implementation of this type should work differently -- e.g. by having a more informative class than Epsilon that can report the precision as a base and exponent. (Another possible idea would be to have floatRadix return recip precision and floatDigits return 1, but that has some oddities around what should happen if the precision is not the reciprocal of a whole number.)

Haskell: Implementing a design with an interface and a polymorphic function

Again I'm requesting comments about how a given design should be implemented in Haskell.
Thanks in advance to everyone providing helpful comments. Also I hope this could be an aid to other Haskell novices like me, having a practical sample code.
This time, we have a polymorphic function doSampling (in module Samples) that takes a generic function f and
a list of reals (indexes) and returns a Samples (indexes, values=f(indexes)). We want implement doSampling only once, as it doesn't matter if is f is a Polynomial or a Sinus. For that,
we have introduced an interface Function, and have Polynomial and Sinus types implement it.
The following is the design being implemented:
Edit 1:
There is a debate on the Function interface (class in Haskell). It has been suggested it is not actually necessary, as doSampling may take a "nude" function (Double -> Double) instead.
But, how to do it, if you need some extra state within the nude function (coeffs for a polynomial, amp+freq+phase for a sinus?
Edit 2:
Very good answers by kosmikus and by Chris Taylor. Thanks.
A key idea in both: have
doSampling :: (Double -> Double) -> [Double] -> Samples
This is: it takes a function (Double -> Double) (instead of Function) and list and returns samples.
My intention was to keep the state of Polynomials and Sinuses. That is not regarded in Chris answer, but it is in kosmikus'. On the other hand, the weak point in kosmikus version could be how to extend its Function definition if you don't have access to the source code.
I would also point out:
Chris' idea of encapsulating a polynomial or a sinus into a function (Double -> Double) by means of a factory function mkPolynomial or mkSinus that generates (using currying?) the desired function taking the apropriate parameters. (Although you can't consult the parameters later).
kosmikous' idea of using value to transform (also using currying?) a Function into a (Double -> Double)
Both answers are worth reading as they have other little Haskell tricks to reduce and simplify code.
In sum
Chris answers does not support keeping the state of a Polynomial or of a Sinus
kosmikus answers is not extensible: adding new type of functions (Cosinus ...)
my answer (being verbose) does overcome the previous downsides, and it would allow (this not necessary for the problem) impose Function types to have more associated-functions apart of value (in the sense of how an java-interfaces work).
My own approach
main (usage)
import Polynomial
import Sinus
import Function
import Samples
-- ...............................................................
p1 = Polynomial [1, 0, 0.5] -- p(x) = 1 + 0.5x^2
s1 = Sinus 2 0.5 3 -- f(x) = 2 sin(0.5x + 3)
-- ...............................................................
-- sample p1 from 0 to 5
m1 = doSampling p1 [0, 0.5 .. 5]
m2 = doSampling s1 [0, 0.5 .. 5]
-- ...............................................................
-- main
-- ...............................................................
main = do
putStrLn "Hello"
print $ value p1 2
print $ value s1 (pi/2)
print $ pairs m1
print $ pairs m2
Function
module Function where
-- ...............................................................
-- "class type" : the types belonging to this family of types
-- must implement the following functions:
-- + value : takes a function and a real and returns a real
-- ...............................................................
class Function f where
value :: f -> Double -> Double
-- f is a type variable, this is:
-- f is a type of the Function "family" not an actual function
Samples
module Samples where
import Function
-- ...............................................................
-- Samples: new data type
-- This is the constructor and says it requieres
-- two list, one for the indexes (xs values) and another
-- for the values ( ys = f (xs) )
-- this constructor should not be used, instead use
-- the "factory" function: new_Samples that performs some checks
-- ...............................................................
data Samples = Samples { indexes :: [Double] , values :: [Double] }
deriving (Show)
-- ...............................................................
-- constructor: it checks lists are equal size, and indexes are sorted
new_Samples :: [Double] -> [Double] -> Samples
new_Samples ind val
| (length ind) /= (length val) = samplesVoid
| not $ isSorted ind = samplesVoid
| otherwise = Samples ind val
-- ...............................................................
-- sample a funcion
-- it takes a funcion f and a list of indexes and returns
-- a Samples calculating the values array as f(indexes)
doSampling :: (Function f) => f -> [Double] -> Samples
doSampling f ind = new_Samples ind vals
where
vals = [ value f x | x <- ind ]
-- ...............................................................
-- used as "error" in the construction
samplesVoid = Samples [] []
-- ...............................................................
size :: Samples -> Int
size samples = length (indexes samples)
-- ...............................................................
-- utility function to get a pair (index,value) out of a Samples
pairs :: Samples -> [(Double, Double)]
pairs samples = pairs' (indexes samples) (values samples)
pairs' :: [Double] -> [Double] -> [(Double, Double)]
pairs' [] [] = []
pairs' [i] [v] = [(i,v)]
pairs' (i:is) (v:vs) = (i,v) : pairs' is vs
-- ...............................................................
-- to check whether a list is sorted (<)
isSorted :: (Ord t) => [t] -> Bool
isSorted [] = True
isSorted [e] = True
isSorted (e1:(e2:tail))
| e1 < e2 = isSorted (e2:tail)
| otherwise = False
Sinus
module Sinus where
-- ...............................................................
import Function
-- ...............................................................
-- Sinus: new data type
-- This is the constructor and says it requieres
-- a three reals
-- ...............................................................
data Sinus = Sinus { amplitude :: Double, frequency :: Double, phase :: Double }
deriving (Show)
-- ...............................................................
-- we say that a Sinus is a Function (member of the class Function)
-- and then, how value is implemented
instance Function Sinus where
value s x = (amplitude s) * sin ( (frequency s)*x + (phase s))
Polynomial
module Polynomial where
-- ...............................................................
import Function
-- ...............................................................
-- Polynomial: new data type
-- This is the constructor and says it requieres
-- a list of coefficients
-- ...............................................................
data Polynomial = Polynomial { coeffs :: [Double] }
deriving (Show)
-- ...............................................................
degree :: Polynomial -> Int
degree p = length (coeffs p) - 1
-- ...............................................................
-- we say that a Polynomial is a Function (member of the class Function)
-- and then, how value is implemented
instance Function Polynomial where
value p x = value' (coeffs p) x 1
-- list of coeffs -> x -> pw (power of x) -> Double
value' :: [Double] -> Double -> Double -> Double
value' (c:[]) _ pw = c * pw
value' (c:cs) x pw = (c * pw) + (value' cs x x*pw)
You certainly don't need the Function class. All this heavyweight class, instance, member variable fluff is one of the things that Haskell is designed to avoid. Pure functions can be much more flexible.
Here's a simple way of doing what you want.
type Sample = ([Double], [Double])
newSample xs vs
| isSorted xs && length xs == length vs = (indices, values)
| otherwise = ([], [])
pairs = uncurry zip
doSampling :: (Double -> Double) -> [Double] -> Sample
doSampling f xs = newSample xs (map f xs)
mkPolynomial :: [Double] -> (Double -> Double)
mkPolynomial coefs x = go coefs
where
go [] = 0
go (c:cs) = c + x * go cs
mkSinus :: Double -> Double -> Double -> (Double -> Double)
mkSinus amp freq phase x = amp * sin (freq * x + phase)
p1 = mkPolynomial [1, 0, 0.5] -- 1 + 0.5x^2
s1 = mkSinus 2 0.5 3 -- 2 sin(0.5x + 3)
m1 = doSampling p1 [0, 0.5 .. 5]
m2 = doSampling s1 [0, 0.5 .. 5]
main :: IO ()
main = do
print $ p1 2
print $ s1 (pi/2)
print $ pairs m1
print $ pairs m2
[Expanded my comment on request.]
I'd probably do this roughly as follows:
import Data.Functor
-- Use a datatype rather than a class. Yes, this makes it harder to
-- add new types of functions later, and in turn easier to define new
-- operations. ("expression problem")
data Function =
Sinus { amplitude :: Double, frequency :: Double, phase :: Double }
| Polynomial { coeffs :: [Double] }
deriving (Show)
-- Interpreting a Function as an actual function.
value :: Function -> (Double -> Double)
value (Sinus amp freq ph) x = amp * sin (freq * x + ph)
value (Polynomial cs) x = value' cs x
-- Rewrite value' to not require non-empty lists. This can also be
-- nicely written as a fold.
value' :: [Double] -> Double -> Double
value' [] _ = 0
value' (c:cs) x = c + x * value' cs x
data Samples = Samples { indexes :: [Double] , values :: [Double] }
deriving (Show)
-- Use Maybe to detect error conditions, instead of strange values
-- such as voidSamples.
newSamples :: [Double] -> [Double] -> Maybe Samples
newSamples ind val
| length ind /= length val = Nothing
| not $ isSorted ind = Nothing
| otherwise = Just (Samples ind val)
doSampling :: (Double -> Double) -> [Double] -> Maybe Samples
doSampling f ind = newSamples ind (map f ind)
isSorted :: (Ord t) => [t] -> Bool
isSorted [] = True
isSorted [e] = True
isSorted (e1:e2:es)
| e1 < e2 = isSorted (e2:es)
| otherwise = False
-- This is just zip.
pairs :: Samples -> [(Double, Double)]
pairs (Samples idxs vals) = zip idxs vals
p1 = Polynomial [1, 0, 0.5] -- p(x) = 1 + 0.5x^2
s1 = Sinus 2 0.5 3 -- f(x) = 2 sin(0.5x + 3)
m1 = doSampling (value p1) [0, 0.5 .. 5]
m2 = doSampling (value s1) [0, 0.5 .. 5]
-- The <$> maps over a Maybe.
main = do
putStrLn "Hello"
print $ value p1 2
print $ value s1 (pi/2)
print $ pairs <$> m1
print $ pairs <$> m2

Strange Haskell type error only happening when currying assertEqual

This code will compile correctly:
import Text.Printf
import Test.HUnit
doubleMe x = x + x
doubleUs x y = doubleMe x + doubleMe y
doubleSmallNumber x = if x > 100 then x else x*2
doubleSmallNumber' x = if x > 100 then x else x*2 + 1
conanO'Brien = "It's a-me, Conan O'Brien!"
main = do
runTestTT $ TestList [TestCase $ ae 4 $ doubleMe 2,
TestCase $ ae 10 $ doubleUs 2 3,
TestCase $ ae 4 $ doubleSmallNumber 2,
TestCase $ ae 1000 $ doubleSmallNumber' 1000,
TestCase $ assertEqual "" "It's a-me, Conan O'Brien!" conanO'Brien]
where ae = assertEqual ""
The output is:
$ clear && ghc baby.hs && ./baby
[1 of 1] Compiling Main ( baby.hs, baby.o )
Linking baby ...
ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog
Cases: 5 Tried: 5 Errors: 0 Failures: 0
When I change the code to:
import Text.Printf
import Test.HUnit
doubleMe x = x + x
doubleUs x y = doubleMe x + doubleMe y
doubleSmallNumber x = if x > 100 then x else x*2
doubleSmallNumber' x = if x > 100 then x else x*2 + 1
conanO'Brien = "It's a-me, Conan O'Brien!"
main = do
runTestTT $ TestList [TestCase $ ae 4 $ doubleMe 2,
TestCase $ ae 10 $ doubleUs 2 3,
TestCase $ ae 4 $ doubleSmallNumber 2,
TestCase $ ae 1000 $ doubleSmallNumber' 1000,
TestCase $ ae "It's a-me, Conan O'Brien!" conanO'Brien]
where ae = assertEqual ""
I get:
[1 of 1] Compiling Main ( baby.hs, baby.o )
baby.hs:12:65:
No instance for (Num [Char])
arising from the literal `1000'
Possible fix: add an instance declaration for (Num [Char])
In the first argument of `doubleSmallNumber'', namely `1000'
In the second argument of `($)', namely `doubleSmallNumber' 1000'
In the second argument of `($)', namely
`ae 1000 $ doubleSmallNumber' 1000'
I don't understand why.
Also does anybody have any ideas for fixing the ld warning:
ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog
This is an example of the monomorphism restriction. ae "looks like a value" (doesn't have arguments) and doesn't have an explicit type, so compiler won't infer a polymorphic type for it.
In first example, it gets type Int -> Int -> Assertion (I think).
In the second, from ae "It's a-me, Conan O'Brien!" conanO'Brien it gets the type String -> String -> Assertion. Remember that the type of integer literals is actually Num a => a, and 1000 gets type String from ae, so the compiler needs an instance Num String.
EDITED: This can be fixed by giving an explicit type annotation: where ae :: (Show a, Eq a) => a -> a -> Assertion = assertEqual "". Or by adding arguments to definition (eta-expanding it): where ae x y = assertEqual "" x y.
It's the monomorphism restriction. The ae function is assigned a monomorphic type. Either turn off the restriction or give ae a type signature.
#augustss and #Alexey Romanov are correct. You can see the inferred type for ae if you move it to the top level and remove the last assertion:
*Main> :t ae
ae :: Integer -> Integer -> Assertion
If you keep ae in the where clause, but add a type signature with a more general type, it will work:
main = do
runTestTT $ TestList [TestCase $ ae 4 $ doubleMe 2,
TestCase $ ae 10 $ doubleUs 2 3,
TestCase $ ae 4 $ doubleSmallNumber 2,
TestCase $ ae 1000 $ doubleSmallNumber' 1000,
TestCase $ ae "It's a-me, Conan O'Brien!" conanO'Brien]
where
ae :: (Show a, Eq a) => a -> a -> Assertion
ae = assertEqual ""
Just to add a footnote, it's overloading that's ruled out by the monomorphism restriction. So, this is ok
foo :: String -> b -> b
foo _ b = b
goo :: (Int, Bool)
goo = (moo 2, moo True) where moo = foo "boo"
but this isn't
hoo :: Eq b => String -> b -> b -> Bool
hoo _ b c = b == c
ioo :: (Bool, Bool)
ioo = (moo 2 2, moo True True) where moo = hoo "boo"
Parametric polymorphism is permitted (and has no performance overhead)!

New to functional programming [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
Hey, I'm really new to Haskell and have been using more classic programming languages my whole life. I have no idea what is going on here. I'm trying to make a very simple Viterbi algorithm implementation, but for only two states (honest and dishonest casino)
I have a problem where I want to address my array, but I don't think I'm getting types right. That or I'm making a new array each time I try to address it - equally stupid. Look at myArray, te infix, and dynamicProgram especially, PLEASE. Pretty pretty please
Code
import Array
import Char
trans :: Int -> Int -> Double -> Double -> Double
trans from x trans11 trans21 =
if (from == 1) && (x == 1)
then trans11
else if (from == 1) && (x == 2)
then (1-trans11)
else if (from == 2) && (x == 1)
then trans21
else (1-trans21)
em :: Char -> [Double] -> Double
em c list = list!! a
where a = digitToInt c
intToChar :: Int -> Char
intToChar n | n == 1 = '1'
| n == 2 = '2'
casino :: Char -> Int -> Int -> [Double] -> [Double] -> Double -> Double -> Double
casino seqchar 1 y em1 em2 t1 t2= 0.5 * (em seqchar em1)
casino seqchar 2 y em1 em2 t1 t2= 0.5 * (em seqchar em2)
casino seqchar x y em1 em2 t1 t2= maximum[ (1 ## y-1)*(em seqchar em1)*(trans 1 x t1 t2),(2 ## y-1)*(em seqchar em2)*(trans 2 x t1 t2) ]
dynamicProgram :: [Char] -> (Char -> Int -> Int -> [Double] -> [Double] -> Double -> Double -> Double) -> [Double] -> [Double] -> Double -> Double -> (Array a b)
dynamicProgram string score list1 list2 trans11 trans21 = myArray 1 len
[score (string!!y) x y list1 list2 trans11 trans21 | x Int -> [Double] -> Array a b
myArray startIndex endIndex values = listArray (startIndex,startIndex) (endIndex,endIndex) values
traceback :: [Char] -> Int -> Int -> [Double] -> [Double] -> Double -> Double -> [Char]
traceback s 1 0 em1 em2 t1 t2 = []
traceback s 2 0 em1 em2 t1 t2 = []
traceback s x y em1 em2 t1 t2 | x##y == (1 ## y-1)*(em (s!!y) em1)*(trans 1 x t1 t2) = '1' : traceback s 1 (y-1) em1 em2 t1 t2
| x##y == (2 ## y-1)*(em (s!!y) em1)*(trans 2 x t1 t2) = '2' : traceback s 2 (y-1) em1 em2 t1 t2
answer :: [Char] -> [Double] -> [Double] -> Double -> Double -> [Char]
answer string list1 list2 t1 t2 = reverse $ maxC : traceback string max end list1 list2 t1 t2 $ dynamicProgram casino string list1 list2 t1 t2
where
end = (length string) + 1
max | maximum (1##end) (2##end) == 1##end = 1
| maximum (1##end) (2##end) == 2##end = 2
maxC = intToChar max
infix 5 ##
(##) i j = myArray ! (i, j)
main = do
putStrLn "What is the sequence to test?"
seq state 1 transmission probability?"
trp1 state 2 transmission probability is " ++ (1-trp1)
putStrLn "What is the state 2 -> state 1 transmission probability?"
trp2 state 2 transmission probability is " ++ (1-trp2)
putStrLn "I assume that the prob of starting in either state is 1/2. Go!"
answer seq st1 st2 trp1 trp2
I copied the code from the edit window (something in stackoverflow's parser is eating part of the code) and tried it on ghci, which found several errors. The first error was:
foo.hs:34:71:
Couldn't match expected type `[e]' against inferred type `(a, b)'
In the second argument of `listArray', namely
`(endIndex, endIndex)'
In the expression:
listArray (startIndex, startIndex) (endIndex, endIndex) values
In the definition of `myArray':
myArray startIndex endIndex values
= listArray (startIndex, startIndex) (endIndex, endIndex) values
The type of listArray is:
listArray :: (Ix i) => (i, i) -> [e] -> Array i e
-- Defined in GHC.Arr
It takes a tuple with the lower and upper bounds and the list. So, the correct expression would probably be:
listArray (startIndex, endIndex) values
And the type of myArray is not Array a b, it is Array Int Double.
The second error was:
foo.hs:43:44:
Couldn't match expected type `a -> b'
against inferred type `[Char]'
In the first argument of `($)', namely
`maxC : (traceback string max end list1 list2 t1 t2)'
In the second argument of `($)', namely
`(maxC : (traceback string max end list1 list2 t1 t2))
$ (dynamicProgram casino string list1 list2 t1 t2)'
In the expression:
reverse
$ ((maxC : (traceback string max end list1 list2 t1 t2))
$ (dynamicProgram casino string list1 list2 t1 t2))
$ is right associative, so the rightmost $ is looked at first. The first parameter to it must be a function, which it will call with its rightmost parameter as the argument. Here, however, it is a list.
The third error was:
foo.hs:51:11:
Couldn't match expected type `Array i e'
against inferred type `Int -> Int -> [Double] -> Array a b'
In the first argument of `(!)', namely `myArray'
In the expression: myArray ! (i, j)
In the definition of `##': ## i j = myArray ! (i, j)
myArray is not an array; it is a function which takes three parameters and constructs an array based on them.
Here probably your being used to more traditional imperative languages is tripping you. In a traditional imperative language, it would be natural to have a global myArray variable which you then can access from the middle of your program. In Haskell however, absent more advanced trickery which you should not try while you are a beginner, a "global" variable is more like a constant value (which is lazily computed on first use, but which as far as you care could have been computed by the compiler while generating your executable). You cannot initialize it from values you read as input.
Your best way around that is to pass the array through the program, which unfortunately will need several changes and negates the usefulness of your ## operator. You can hide the passing of the array in several more advanced ways, but while learning it is best to be more explicit.
The last error was:
foo.hs:63:4:
Couldn't match expected type `[a]' against inferred type `IO ()'
In the first argument of `(++)', namely
`putStrLn
"I assume that the state 1 -> state 2 transmission probability is "'
In the expression:
(putStrLn
"I assume that the state 1 -> state 2 transmission probability is ")
++
(1 - trp1)
In a 'do' expression:
(putStrLn
"I assume that the state 1 -> state 2 transmission probability is ")
++
(1 - trp1)
This has two errors: the one the compiler complained about is a precedence problem, as the compiler-added parenthesis readly show, and which can easily be fixed by correct application of either parenthesis or the $ operator. The other error, which you will find after you fix this one, is that you cannot concatenate a string and a number; you have to convert the number to a string.
This was all without looking at the algorithm or even most of the code, just looking at the compiler errors. If you want a two-dimensional array, for instance, the correct expression for the first error would be:
listArray ((startIndex, startIndex), (endIndex, endIndex)) values
Now both bounds are tuples, and its type is Array (Int, Int) Double.
You can rewrite the trans-function like this:
trans :: Int -> Int -> Double -> Double -> Double
trans 1 1 trans11 trans21 = trans11
trans 1 2 trans11 trans21 = 1-trans11
trans 2 1 trans11 trans21 = trans21
trans _ _ trans11 trans21 = 1-trans21

Resources