Reputation:
I'm trying to recursively find the ith positive integer for which the predicate is true. I need to keep it general for every function.
ithTrueValue :: (Int -> Bool) -> Int-> Int
ithTrueValue func i
| i < 1 = error "Integer MUST BE greater than 0"
| ithTrueValue func i = 1 + ithTrueValue(func i-1 )
| otherwise = ithTrueValue(func i-1)
I get a type error:
ERROR file:.\new 10.hs:6 - Type error in guard
*** Term : ithTrueValue func i
*** Type : Int
*** Does not match : Bool
Upvotes: 0
Views: 862
Reputation: 52029
Your error is with this line:
| ithTrueValue func i = 1 + ithTrueValue(func i-1 )
^^^^^^^^^^^^^^^^^^^^^^^^^
iTruthValue
takes 2 arguments, but because of the parens you're only calling it with one.
You probably wanted to write something like:
| ithTrueValue func i = 1 + ithTrueValue func (i-1)
Upvotes: 0
Reputation: 53881
The problem is that ithTrueValue func i
isn't boolean, it's an integer. I think there are really 4 cases to deal with here,
i
is an insane value, like -1 or similari
th time it's true.With that in mind let's restructure your code a bit
ithTrueValue f i = go 0 f i
so we're using this helper function called go
which is going to count up the integers and keep track of what integer we're at
where go _ _ i | i <= 0 = error "i must be a positive integer" -- case 1.
go curr f i | f curr = if i == 1
then curr -- case 4.
else go (curr + 1) f (i - 1) -- case 2.
| otherwise = ??? -- case 3.
Where ???
is the case where the predicate is false. I'll leave it to you to figure out what to do in this case.
Now this works, but it's very.. low level. Explicit recursion is not the nicest way to write this sorta stuff. More pleasant is to rely on higher order functions, specifically
filter :: (a -> Bool) -> [a] -> [a]
So this will run down the list and leave all values where the predicate is true
ithTrueValue i f = ??? filter f [0..]
where ???
get's the ith
value of the list. For this we use
(!!) :: [a] -> Int -> a
which just selects an index
ithTrueValue i f = filter f [0..] !! i
Upvotes: 5