News aggregator

Monoid instance for IO

libraries list - Thu, 11/13/2014 - 5:13pm
I would like to add the following `Monoid` instance for `IO` to `Data.Monoid`: ``` instance Monoid a => Monoid (IO a) where mempty = pure mempty mappend = liftA2 mappend ``` I describe the benefit of this particular instance in this blog post: http://www.haskellforall.com/2014/07/equational-reasoning-at-scale.html ... and Conal Elliot describes the general trick of recursively lifting `Monoid` instances in his type class morphisms paper: http://conal.net/papers/type-class-morphisms/type-class-morphisms-long.pdf The primary benefit of the `Monoid` instance is that it chains well with other `Monoid` instances in `base` to create derived `Monoid` instances. The following types are examples of useful derived `Monoid` instances: ``` IO () -- Because `()` is a `Monoid` a -> IO () -- Because `a -> r` is a `Monoid` if `r` is a `Monoid` IO (a -> IO ()) -- This comment explains the utility of this instance: http://www.reddit.com/r/haskell/comments/22bn1m/monads_lifting_join_and_sideeffectin
Categories: Offsite Discussion

Neil Mitchell: Operators on Hackage

Planet Haskell - Thu, 11/13/2014 - 3:32pm

Summary: I wrote a script to list all operators on Hackage, and which packages they are used by.

In GHC 7.10 the *> operator will be moving into the Prelude, which means the Shake library will have to find an alternative operator (discussion on the mailing list). In order to pick a sensible operator, I wanted to list all operators in all Hackage packages so I could be aware of clashes.

Note that exported operators is more than just those defined by the package, e.g. Shake exports the Eq class, so == is counted as being exported by Shake. However, in most cases, operators exported by a package are defined by that package.

Producing the file

First I downloaded the Hoogle databases from Hackage, and extracted them to a directory named hoogle. I then ran:

ghc --make Operators.hs && operators hoogle operators.txt

And uploaded operators.txt above. The code for Operators.hs is:

import Control.Exception.Extra
import Control.Monad
import Data.List.Extra
import System.Directory.Extra
import System.Environment
import System.FilePath
import System.IO.Extra

main = do
[dir,out] <- getArgs
files <- listFilesRecursive dir
xs <- forM files $ \file -> do
src <- readFileUTF8' file `catch_` \_ -> readFile' file `catch_` \_ -> return ""
return [("(" ++ takeWhile (/= ')') x ++ ")", takeBaseName file) | '(':x <- lines src]
writeFileUTF8 out $ unlines [unwords $ a : nub b | (a,b) <- groupSort $ concat xs]

This code relies on the normal packages distributed with GHC, plus the extra package.

Code explanation

The script is pretty simple. I first get two arguments, which is where to find the extracted files, and where to write the result. I then use listFilesRecursive to recursively find all extracted files, and forM to loop over them. For each file I read it in (trying first UTF8, then normal encoding, then giving up). For each line I look for ( as the first character, and form a list of [(operator-name, package)].

After producing the list, I use groupSort to produce [(operator-name, [package])] then writeFileUTF8 to produce the output. Running the script takes just over a minute on my ancient computer.

Writing the code

Writing the code to produce the operator list took about 15 minutes, and I made some notes as I was going.

  • I started by loading up ghcid for the file with the command line ghcid -t -c "ghci Operators.hs". Now every save immediately resulted in a list of warnings/errors, and I never bothered opening the file in ghci, I just compiled it to test.
  • I started by inserting take 20 files so I could debug the script faster and could manually check the output was plausible.
  • At first I wrote takeBaseName src rather than takeBaseName file. That produced a lot of totally incorrect output, woops.
  • At first I used readFile to suck in the data and putStr to print it to the console. That corrupted Unicode operators, so I switched to readFileUTF8' and writeFileUTF8.
  • After switching to writeFileUTF8 I found a rather serious bug in the extra library, which I fixed and added tests for, then made a new release.
  • After trying to search through the results, I added ( and ) around each operator to make it easier to search for the operators I cared about.

User Exercise

To calculate the stats of most exported operator and package with most operators I wrote two lines of code - how would you write such code? Hint: both my lines involved maximumBy.

Categories: Offsite Blogs

Ideas for improving build tools in cases where stackage doesn't apply

Haskell on Reddit - Thu, 11/13/2014 - 2:52pm

In the course of the recent discussions on upper bounds, stackage, and the PVP, it has become clear to me that the two camps are largely talking past each other. So I thought it would be helpful to have a post for conversation on a restricted domain. Specifically, how to improve our tools for dealing with situations where stackage and cabal freeze do not apply.

The author of stackage, /u/snoyberg, has recognized the existence of this case here:

I mentioned in my blog post that I often times need to drop down to Hackage to perform my curation work. And I fully expect that there are cases for which Stackage isn't sufficient, maintaining a core library with a long support cycle being one of them. That's how I do dev on Yesod and other libraries I maintain, for example.

As near as I can tell, this is the case that the pro-PVP camp is usually referring to when they argue for upper bounds. A number of ideas have been put forth such as:

  • Introduce a new concept to distinguish between hard upper bounds (above which the build in known to fail) and soft upper bounds (above which the build has not been tested or does not exist).

  • Make upper bounds more like suggestions than hard restrictions. (To some extent, the recent addition of --allow-newer does this.)

  • Augment the use of upper bounds with the notion of "implicit blacklisting", an idea that I put forth here.

  • Instead of using the convention of specifying an open upper bound (i.e. "< 1.3"), use closed upper bounds (i.e. "<= 1.3.0.4").

  • Make hackage require upper bounds on all dependencies

  • Have hackage make sure you're not doing a minor version bump when your changes require a major bump.

  • Implement an automated system for building and testing packages whenever new versions of dependencies are released and automatically adjusting upper bounds appropriately.

Duncan Coutts had a really nice outline of some of these (and some other possibilities) a couple months ago over at the Well-Typed blog.

This post is for the discussion of this subset of "cabal hell" build problems. What are your suggestions for improving our tools for managing these situations? Please restrict the discussion to this specific sub-problem.

submitted by mightybyte
[link] [14 comments]
Categories: Incoming News

Ideas for improving build tools in cases where stackage doesn't apply

Haskell on Reddit - Thu, 11/13/2014 - 2:51pm

In the course of the recent discussions on upper bounds, stackage, and the PVP, it has become clear to me that the two camps are largely talking past each other. So I thought it would be helpful to have a post for conversation on a restricted domain. Specifically, how to improve our tools for dealing with situations where stackage and cabal freeze do not apply.

The author of stackage, /u/snoyberg, has recognized the existence of this case here:

I mentioned in my blog post that I often times need to drop down to Hackage to perform my curation work. And I fully expect that there are cases for which Stackage isn't sufficient, maintaining a core library with a long support cycle being one of them. That's how I do dev on Yesod and other libraries I maintain, for example.

As near as I can tell, this is the case that the pro-PVP camp is usually referring to when they argue for upper bounds. A number of ideas have been put forth such as:

  • Introduce a new concept to distinguish between hard upper bounds (above which the build in known to fail) and soft upper bounds (above which the build has not been tested or does not exist).

  • Make upper bounds more like suggestions than hard restrictions. (To some extent, the recent addition of --allow-newer does this.)

  • Augment the use of upper bounds with the notion of "implicit blacklisting", an idea that I put forth here.

  • Instead of using the convention of specifying an open upper bound (i.e. "< 1.3"), use closed upper bounds (i.e. "<= 1.3.0.4").

  • Make hackage require upper bounds on all dependencies

  • Have hackage make sure you're not doing a minor version bump when your changes require a major bump.

  • Implement an automated system for building and testing packages whenever new versions of dependencies are released and automatically adjusting upper bounds appropriately.

Duncan Coutts had a really nice outline of some of these (and some other possibilities) a couple months ago over at the Well-Typed blog.

This post is for the discussion of this subset of "cabal hell" build problems. What are your suggestions for improving our tools for managing these situations? Please restrict the discussion to this specific sub-problem.

submitted by mightybyte
[link] [comment]
Categories: Incoming News

Suggest a project where writing my own Monad would be useful?

Haskell on Reddit - Thu, 11/13/2014 - 1:21pm

I've come into significant contact with monads, as I guess you have to in haskell, but I haven't yet needed to really implement them myself, and feel like im missing out. Looking for ideas that might remedy this! thanks

submitted by fruitbooploops
[link] [16 comments]
Categories: Incoming News

Proposal: Make GHC.Arr.listArray slightly stricter to allow fusion

libraries list - Thu, 11/13/2014 - 12:22pm
Currently, GHC.Arr.listArray is pretty lazy: listArray (1,3) $ [1,2,3] ++ undefined will work perfectly fine. This is actually lazier than the current array: array (1,3) $ [(1,1), (2,2), (3,3)] ++ undefined = undefined Unfortunately, I don't think it's possible to make listArray fuse with a list producer while preserving quite that level of laziness. If we're willing to be slightly stricter, however, I think everything works. Specifically, I propose that we allow listArray (length xs) (xs ++ _|_) = _|_ The resulting listArray code is below. {-# INLINE mylistArray #-} listArray :: Ix i => (i,i) -> [e] -> Array i e listArray (l,u) es = runST (ST $ \s1# -> case safeRangeSize (l,u) of { n< at >(I# n#) -> case newArray# n# arrEleBottom s1# of { (# s2#, marr# #) -> let fillFromList y r i# s3# | isTrue# (i# ==# n#) = s3# | otherwise = case writeArray# marr# i# y s3# of s4# -> r (i# +# 1#) s4# in case foldr fillFromList
Categories: Offsite Discussion

Created my first monoid!

Haskell on Reddit - Thu, 11/13/2014 - 11:01am

https://github.com/ssadler/many

I made a monoid instance to represent a collection of values of different types where the collection can be combined. The monoid is very similar to Map.Map's monoid instance. This is kind of like a more flexible version of Either / Maybe, which are ambiguous to the types of their contents but which also support exclusivity. It's really just a wrapper around a collection of maybes.

I'm not sure if the monoid instance is "correct" here, according to category theory and whatnot. Perhaps it should require all it's contents to be monoid also? My use case is to be able to update the container with a new value and know if it's complete.

Also, looking at the monoid page on hackage, there's lots of interesting looking things like All and Sum and Endo, which look like they are perhaps relevant but I'm not sure how to use them. Can anyone elucidate?

submitted by scottansan
[link] [11 comments]
Categories: Incoming News

haskell tutorials books

del.icio.us/haskell - Thu, 11/13/2014 - 10:23am
Categories: Offsite Blogs

How is maintaining the iCalendar package?

haskell-cafe - Thu, 11/13/2014 - 9:34am
Hello fellow Haskellers, anybody knows who is maintaining https://github.com/tingtun/iCalendar ? I have tried to email the maintainer listed on Github, but his activity seems quite low. Posting it here hoping to get a bit more resonance. Alfredo _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Generating valid html

haskell-cafe - Thu, 11/13/2014 - 12:44am
Hello list, I have a question. How to create a DSL for HTML generation, that would (statically) allow only valid HTML to be generated? Parent - child relations, valid attributes only. Or does such a DSL already exist, perhaps?
Categories: Offsite Discussion