Lazyness and forM_

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Lazyness and forM_

Marc Busqué
Hi there!

I'm using [selda](https://github.com/valderman/selda) package to work
with databases.

I'm trying to write a function to generate several tables at once. In
the following examples, `categories` and `expenses` are two selda
`Table`. The other functions in use and their respective imports should
be self-evident:

If I do:

```
migrate :: IO ()
migrate = do
     dir <- dBDir
     createDirectoryIfMissing True dir
     forM_ (categories, expenses)
        $ withDB . createTable
```

tables are not actually created.

However, if I do:

```
migrate :: IO ()
migrate = do
     dir <- dBDir
     createDirectoryIfMissing True dir
     withDB . createTable $ categories
     withDB . createTable $ expenses
```

Both tables are actually created.

So it seems like the thugs created with `formM_` are actually never
executed. Is it so? I'm new with Haskell and it seems strange for me. If
it is so, doesn't make it useless `forM_` for IO?

Furthermore, I can't reproduce it in ghci. Doing this:

```
["a", "b"] `forM_` print
```

Actually prints both `"a"` and `"b"`.

Thanks for any enlightment.

Marc Busqué
http://waiting-for-dev.github.io/about/
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Lazyness and forM_

Kim-Ee Yeoh
Administrator
Hi Marc, and welcome to the haskell beginners list.

```
migrate :: IO ()
migrate = do
    dir <- dBDir
    createDirectoryIfMissing True dir
    forM_ (categories, expenses)
       $ withDB . createTable
```

tables are not actually created.


Well, 

forM_ (categories, expenses) $ withDB . createTable

is equivalent to 

withDB . createTable $ expenses.

So exactly one table is created.

 
```
["a", "b"] `forM_` print
```

Actually prints both `"a"` and `"b"`.


Here the code uses square brackets--and so we have honest-to-goodness lists--whereas the previous used parentheses.

See what happens with: ("a","b") `forM_` print.

Marc: Feel free to write to the haskell-cafe mailing list for questions such as this. Fortuitously in this case, it turns out that your query needed knowledge only about the forM* combinators and--ever since their ilk was generalized--the known instances declared for the Traversable constraint. As you explore the domain-specific package "selda" further, you will find more people acquainted with the package over at the cafe than here in beginners. Suffice to say, everyone here in this list is also in cafe, which is also open to beginners questions.

p.s. Veterans would recognize this as ye olde controversy on the Foldable instance for pairs introduced in GHC 7.10.x. The controversy still simmers apparently because there isn't an instance for triples and higher tuples in the latest and greatest GHC 8.4.1. We are at the mercy of this potentially toe-stubbing absence of uniformity.

-- Kim-Ee


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Lazyness and forM_

Marc Busqué
On Fri, 13 Apr 2018, Kim-Ee Yeoh wrote:

> Well, 
>
> forM_ (categories, expenses) $ withDB . createTable
>
> is equivalent to 
>
> withDB . createTable $ expenses.
>
> So exactly one table is created.

Oops, you are right.

>       ```
>       ["a", "b"] `forM_` print
>       ```
>
>       Actually prints both `"a"` and `"b"`.
>
>
> Here the code uses square brackets--and so we have honest-to-goodness lists--whereas the previous used parentheses.
>
> See what happens with: ("a","b") `forM_` print.
Now I feel embarrassed I overlooked that :)

I used a tuple instead of a list because in selda `Table` are type-safe.
So `categories` and `expenses` are different types and they can't go in
the same list.

So I guess, once the `forM_` mistery is gone, I can boil down my problem
to something very different. As it has nothing to do with the current
subject, I'll submit another question.

> Marc: Feel free to write to the haskell-cafe mailing list for questions such as this. Fortuitously in this case, it turns out that your query
> needed knowledge only about the forM* combinators and--ever since their ilk was generalized--the known instances declared for the Traversable
> constraint. As you explore the domain-specific package "selda" further, you will find more people acquainted with the package over at the cafe
> than here in beginners. Suffice to say, everyone here in this list is also in cafe, which is also open to beginners questions.

And following your recommendation I'll submit that question in the
haskell-cafe mailing list :)

Thank you very much for your help :)

Marc Busqué
http://waiting-for-dev.github.io/about/
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners