1

Someone can please explain why I am getting a loop in this code?

module Main where

import Data.List.Split
import Data.Maybe
import Text.Read

main :: IO ()
main = print (snd (toInmetDate "01/02/2012"))

type P a = (Bool, a)

readP :: (Read a) => String -> P a
readP text
  | isJust value    = (True, fromJust value)
  | isNothing value = (False, read "0")
  where value = readMaybe text

data InmetDate = InmetDate {dia :: P Int, mes :: P Int, ano :: P Integer}
  deriving (Show, Read)

toInmetDate :: String -> P InmetDate
toInmetDate x = if length l == 3
  then  (True, InmetDate (readP ds) (readP ms) (readP as))
  else  (False, InmetDate (False, 0) (False, 0) (False, 0))
  where (l,ds:ms:as:_) = (splitOn "/" x, l ++ replicate 20 "NULL")

I would state that, when I make:

  where (l,ds:ms:as:_) = (splitOn "/" x, l ++ replicate 20 "NULL")

equal to:

  where (ds:ms:as:_) = l ++ replicate 20 "NULL"
        l = splitOn "/" x

the code work perfectly.

RomuloPBenedetti
  • 163
  • 2
  • 12
  • 1
    Please, if downvoting, let me at last know why so I can figure what is wrong, thanks... – RomuloPBenedetti Nov 13 '16 at 03:49
  • 1
    I didn't downvote, but if I were in an unreasonable mood then I might have due to the code fragment not compiling (needs a few imports, a `main` for testing). – Thomas M. DuBuisson Nov 13 '16 at 04:40
  • There appears to be a downvote on a lot of haskell questions lately. Maybe someone is disgruntled and trying to demoralize the community. – luqui Nov 13 '16 at 10:43
  • Sad, I'm getting some more contact with Haskell after my first contact some years ago, and finding it a beautiful language, somewhat hard, but very beautiful. – RomuloPBenedetti Nov 14 '16 at 16:15

1 Answers1

3

In your original, the value of l depends on a tuple that is recursively defined in terms of l. In the change, l depends solely on the value of splitOn "/" x.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • 2
    The strictness of the pattern matching on the second element of the tuple can cause a lot of confusion. For example, explicit laziness works `where (l,~(ds:ms:as:_)) = (splitOn "/" x, l ++ replicate 20 "NULL")` – Thomas M. DuBuisson Nov 13 '16 at 04:39
  • After some more search about strictness I believe I finally understood it, I misunderstood haskell as a `lazy` instead of `non-strict` language – RomuloPBenedetti Nov 13 '16 at 06:10
  • 1
    @RomuloPBenedetti, I'm glad you feel satisfied, but I feel like i need to point out that you probably don't understand it. *lazy* and *non-strict* mean exactly the same thing as far as what output you will get (there is a [subtle distinction](http://stackoverflow.com/a/7141537/33796) which doesn't matter here). I think Thomas is right on, this is about the strictness of pattern matches. – luqui Nov 13 '16 at 10:51
  • 1
    You can read a little about lazy pattern matches [here](https://wiki.haskell.org/Lazy_pattern_match) which might help, though I was unable to find an explanation I really liked. – luqui Nov 13 '16 at 10:58
  • Ok confuse, let me see it again... So Haskell is not purely lazy, only purely non-strict, from outside to inside reduction, but, by what I understood now, non-strict evaluations don't need to be lazy computationally saying. Now, the problem, by what I've understood [here](https://wiki.haskell.org/Lazy_vs._non-strict): Is that pattern matching in particular is strict what forces non lazyness, because of some inplications you point on your link? Like avoiding patterns overlapping? – RomuloPBenedetti Nov 14 '16 at 16:09