3

I'm new to Haskell, and trying to do the following:

takeWhile (length < 3) [[1],[1,2],[1..3],[1..4]]. But this gives an error which I believe is because takeWhile would test length < 3 [1] instead of length [1] < 3, which is what would work. Do I to make [[1],[1,2],[1..3],[1..4]] into a list of lengths and then do a takeWhile (< 3) for that list of lengths? Or is there a way to do it by directly testing lengths?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
TheStrangeQuark
  • 2,257
  • 5
  • 31
  • 58
  • 4
    You want to compose the test "is less than 3" and the "give me the length" function. You can either write `(\ xs -> length xs < 3)` or in point-free style `((< 3) . length)`. – gallais Mar 09 '17 at 03:52
  • By the way your intuition about `length < 3 [1]` is correct: that can not work. More precisely, it would be `(length < 3) [1]`. This would first compare the function `length` and the number `3`, which is already wrong. But even if that somehow worked and produced a boolean result for the comparison, then said boolean would be applied to `[1]` as if it were a function, which is again wrong. – chi Mar 09 '17 at 14:05
  • `(length < 3)` --> `((<) length 3)` --> `((<) <$> length <*> pure 3)` and suddenly it works. – Will Ness Mar 09 '17 at 22:48

1 Answers1

5

You can compose length and (< 3) to achieve what you want:

takeWhile ((< 3) . length) [[1],[1,2],[1..3],[1..4]]
Michael Kohl
  • 66,324
  • 14
  • 138
  • 158