0

I have to find a function g : [Bool] -> Integer such that g gives lowest ubication where True is in a list of booleans. For example,

g [False , False , False , False , True , False , True] ==> 5
g [False , True , True , False , False] ==> 2
g [] ==> ***Exception: empty list
g [False , False] ==> ***Exception: There is no True in your list

I am not too interested in cases where the function takes [] or a list where there is no True because I am working on a program where the boolean list is infinite and it's proved that there always exist True. I think a beginning of the definition of the following:

g :: [Bool] -> Integer
g xs | xs == [] = error "empty list"
     | not (and xs) = error "There is no True in your list"
     | otherwise = ...

Can you help me to find ..., please? Thank you very much.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
joseabp91
  • 305
  • 2
  • 8
  • Your second guard look wrong to me, if I understand your requirements properly. Moreover, I don't think you can rule out this case from the start, your function has to just run forever anyway. – Jean-Baptiste Potonnier Feb 02 '17 at 19:19

3 Answers3

5

Probably the easiest way to do this is using findIndex :: (a -> Bool) -> [a] -> Maybe Int:

import Data.List(findIndex)
import Data.Maybe(fromJust)

g = fromJust . findIndex id

Here you thus use id as "predicate" such that True is accepted and False fails the test. Since in your question you state you know such element always exists, you can use fromJust to "chomp of the Just" so to speak.

In your examples you seem to use "1-indexed" lists, in that case you can define:

-- 1-indexed
import Data.List(findIndex)
import Data.Maybe(fromJust)

g = (1+) . fromJust . findIndex id

In ghci:

Prelude Data.Maybe Data.List> let g = (1+) . fromJust . findIndex id
Prelude Data.Maybe Data.List> g [False , False , False , False , True , False , True]
5
Prelude Data.Maybe Data.List> g [False , True , True , False , False]
2
Prelude Data.Maybe Data.List> g []
*** Exception: Maybe.fromJust: Nothing
Prelude Data.Maybe Data.List> g [False,False]
*** Exception: Maybe.fromJust: Nothing

A final note: it should be:

     | not (or xs) = error "There is no True in your list"

and not

     | not (and xs) = error "There is no True in your list"

since and is only True if all elements are True.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
3

another approach, without error handling

> fst . head . filter snd . zip [1..]
karakfa
  • 66,216
  • 7
  • 41
  • 56
2

I'd think that

(1+) . length . takeWhile not

should do that. You can leave out the (1+) if you go for 0 based indexes, that is, indexes that would work with (!!)

Ingo
  • 36,037
  • 5
  • 53
  • 100