简体   繁体   中英

Haskell Type Error (Int -> Bool Function Parameter)

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

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,

  1. i is an insane value, like -1 or similar
  2. The predicate is true at the current integer,
  3. The predicate is false at the current integer
  4. The predicate is true and this is the i 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

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM