News aggregator

Help wanted with a web framework comparison matrix

Haskell on Reddit - Mon, 10/19/2015 - 3:04am

I want to switch away from Rails, and would like to see how the Haskell frameworks support the main features:

https://docs.google.com/spreadsheets/d/1H13X4xmMw5YBD5nCp7tRXDD3gMEiFjbGXn3_Np7nozU/edit#gid=0

Thanks for any feedback, here or as a comment on the spreadsheet.

submitted by whither-the-dog
[link] [20 comments]
Categories: Incoming News

FP Complete: Stackage Badges

Planet Haskell - Sun, 10/18/2015 - 11:00pm

This is a guest blog from Konstantin Zudov, who has been making a number of wonderful enhancements to the Stackage Server website.

Snapshot badges for packages on Stackage

Stackage Server just got a new feature: snapshot badges. Take a look:

  • stack/lts-2:
  • stack/lts-3:
  • stack/lts (the latest):
  • stack/nightly:

Package authors can add the badges to their README.md to tell users in which snapshots the package is present and provide a link to the package page.

Here is an example of how that can be done:

# PackageName [![packagename on Stackage LTS 2](http://stackage.org/package/packagename/badge/lts-2)](http://stackage.org/lts-2/package/packagename) [![packagename on Stackage LTS 3](http://stackage.org/package/packagename/badge/lts-3)](http://stackage.org/lts-3/package/packagename) [![packagename on Stackage Nightly](http://stackage.org/package/packagename/badge/nightly)](http://stackage.org/nightly/package/packagename)

In case of stack it would look like:

Stack

Categories: Offsite Blogs

Christopher Allen: Either and (,) in Haskell are not arbitrary

Planet Haskell - Sun, 10/18/2015 - 6:00pm

Alternate title: Unnecessary particularity considered harmful

Since I’d rather explain this in O(1) rather than O(twitter) time, this is a brief rundown of why the way type constructors and constructor classes work in Haskell is not arbitrary. The post is not a tutorial on higher-kinded types, constructor classes, or functor. Don’t know these things? I write stuff so you can learn ’em.

First, the data types we’re dealing with:

data Either a b = Left a | Right b -- sorta fake data (,) a b = (a, b)

We’ll use Functor to make the point, and Functor looks like this:

class Functor f where fmap :: (a -> b) -> f a -> f b

Some of the post-FTP drama has included people asserting that the way the Foldable instances for Either and (,) work is arbitrary. Not so. They work on the same principle as the Functor instances:

Prelude> fmap (+1) (Right 1) Right 2 Prelude> fmap (+1) (Left "blah") Left "blah" Prelude> fmap (+1) (0, 0) (0,1)

The first thing to recognize is that Left and Right in Either mean nothing to your program and similarly the first and second positions in (,) mean nothing in and of themselves. Because type constructors in Haskell work the same way as data constructors and functions in general do, the way their instances work is the only way they could work. Either and (,) will always have one type argument that gets mapped and one that does not. It doesn’t really matter which data constructor that is; we can only benefit by letting the consistent semantics of Haskell pick the type argument for us.

The only useful purpose a Functor for Either can ever have is to have one type which is transformed by the lifted functions and one which is not. If you want to be able to pick arbitrary targets, then you want lenses rather than a typeclass. If you want to able to transform both, then you want Bifunctor.

Note that with bimap in the Bifunctor class you have to provide two functions you’re mapping rather than one because the types a and b could vary and be different types. Even if they are the same type, you can’t write the Functor instance as if they were because the Either and (,) are defined with two distinct type arguments.

If you want a “tuple” of values that were all of the same type…well, go ahead. You can write it yourself:

-- We use this in the book to demonstrate how -- type constructors and constructor classes -- work in Haskell, as it happens. data Pair a = Pair a a deriving (Eq, Show) instance Functor Pair where fmap f (Pair a a') = Pair (f a) (f a')

Then to see how the Functor for this behaves:

Prelude> fmap (+1) (Pair 1 1) Pair 2 2 Prelude> fmap show (Pair 1 1) Pair "1" "1" Prelude> fmap show (Pair 1 9001) Pair "1" "9001"

A Functor for (,) can only ever map over one of the fields of the type. It might as well be the one that occurs naturally from the order of arguments to the type constructor (read: functions). length written in terms of Foldable has nothing to do with the contents of the Foldable structure; it has to do with the structure itself. You wouldn’t expect length of a list of lists to measure the length of one or more of the sublists:

Prelude> length [[], []] 2

You would expect it to measure how many cons cells were in the outermost list. Unless you lifted it. If you lifted it, then you could get the measure of all the list values contained within! (this is why we have fmap)

Prelude> fmap length [[], ["lol"]] [0,1] Prelude> (fmap . fmap) length [[], ["lol"]] [[],[3]] -- Doesn't change for Maybe Prelude> length (Just "blah") 1 Prelude> fmap length (Just "blah") Just 4 Prelude> fmap length (Nothing :: Maybe String) Nothing

Similarly, no matter what food you move around on your plate, length for (,) is never going to do anything but return 1 because there’s always one value of the type you’re folding over with (,). Even if you add type lambdas.

Prelude> length ("blah", "") 1 -- unless we lift it over the tuple structure. Prelude> fmap length ("blah", "") ("blah",0) Prelude> fmap length ("blah", "Papuchon") ("blah",8)

Want to map over the left-hand side? Use Bifunctor:

Prelude> import Data.Bifunctor Prelude> :t first first :: Bifunctor p => (a -> b) -> p a c -> p b c Prelude> :t second second :: Bifunctor p => (b -> c) -> p a b -> p a c Prelude> first length ("blah", "Papuchon") (4,"Papuchon") Prelude> second length ("blah", "Papuchon") ("blah",8)

Or lenses! Whatever you like!

The Functor and Foldable for Either and (,) can only ever do one useful thing. We may as well make it so we know exactly which type is being mapped over by looking at the type. What Functor and Foldable do, how they work, is essentially what the combination of higher kinded types and typeclasses into constructor classes is for. This is their purpose for existing. If you want to address more structure than what Functor/Foldable let you talk about, then use Bifunctor or Bifoldable. If you want to choose arbitrary targets, then use lenses and prisms. There’s no reason to break the consistent and predictable semantics of the language because the (necessary by construction!) Functor instance for Either or (,) appears arbitrary to you. In fact, they’re the complete opposite of arbitrary or contingent because their instances follow directly from how the datatypes are defined. This uniqueness and necessity is why we can have the DeriveFunctor and DeriveFoldable extensions which will generate Functor and Foldable instances knowing only the definition of a datatype.

Addendum

It doesn’t matter if the definition of Either was:

data Either a b = Left b | Right a

It matters that a default exists and is chosen for the Functor because that’s the only reason to make something Left or Right. Contrary to developer intuitions, Right doesn’t mean “success”. The data constructors of Either are defined by what the Functor/Applicative/etc. instances do.

I’ve used Left to indicate “success” in situations where I want to stop fmap’ing a computation that might fail. It is the picking-of-a-winner that Haskell’s semantics induce that is valuable and not arbitrary. What is arbitrary is what we call left and right and the syntactic position of their type arguments in the type constructor. There’s much less utility in an Either that doesn’t have a Functor with a default target.

Further, they aren’t arbitrary. Following from the definition of arbitrary that Google provided:

based on random choice or personal whim, rather than any reason or system.

We can break it down as follows:

  1. Is there a reason the Either Functor works the way it does? Yes, it makes the datatype more useful in that it gives us a biased-choice Functor which is frequently useful regardless of whether the biased-target represents success or not. The way Functor behaves is useful insofar as its only reason for existing is to pick one of the two exclusive choices. There is no reason for programmers to favor the target being Left or Right. Those words mean nothing and word/name-fetishism kills software reuse and modularity.

  2. Is there a systematic cause for why the Either Functor works the way it does? Yes, cf. Jones’ work on Gofer dating to 1993/1994. The way the Functor behaves is necessary and follows from how the language works in a natural way. You can make a learner predict what the Either Functor does if you teach them how HKTs and constructor classes work. I’ve done this with learners before. This isn’t surprising if you know Haskell.

Summary

It does not matter whether one of your types is going to be in the Left or Right data constructor, all that matters is what you want your Functor-target to be. Not having a universal winner for Left or Right being the Functor target is bizarre and counter-productive. You can not and will not ever have a single Functor that lets you pick either/or of Left or Right because a != b.

If you want to map over your “error” value, I have news for you! Right just became your error value. The names Left and Right mean nothing. The code is what it does. If you want to be able to arbitrarily pick Left, Right or both as a target, what you want is Bifunctor or a prism. It is madness to give programmers an avenue to introduce useless arbitrariness to their code. Preventing the proliferation of meaningless difference is an excellent way for people doing PL to improve a language.

We’ve covered both ways in which the Functor instance is not arbitrary, due to being both necessary and useful. We can also see that the way the Either Functor works is neither random nor based on whim.

I know this site is a bit of a disaster zone, but if you like my writing or think you could learn something useful from me, please take a look at the book I've been writing with my coauthor Julie. There's a free sample available too!

Posted on October 19, 2015

Categories: Offsite Blogs

MonadFix wiki confusion

haskell-cafe - Sun, 10/18/2015 - 3:40pm
Hello, the MonadFix wiki at https://wiki.haskell.org/MonadFix has a statement that I feel is a bit misleading. In section "2.2 Lazy algorithm interleaved with effects", it claims that making the BTree data structure strict doesn't cause endless recursion. Well, that's true, but that's just because rep_x_sum returns a tuple containing the BTree and the summed values of the current subtree, and the tuple is lazily constructed - postponing the construction of the tree value. So highlighting the fact that the function still works when the BTree structure is made strict is kind of a red herring. Maybe the confusion could be avoided by removing the part about making BTree strict, or adding a note about the tuple still ensuring lazy construction? -- Samuel
Categories: Offsite Discussion

STM and garbage collector

haskell-cafe - Sat, 10/17/2015 - 5:11pm
If a thread is blocking indefinitely in an STM transaction (reading from a queue to which nobody else has a reference and thus can not write into), is the runtime smart enough to GC the thread? Or do I have to kill the thread manually? _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Core libraries

glasgow-user - Fri, 10/16/2015 - 9:21am
Hello GHC users, For various reasons i'm trying to package something which is compatible with/equivalent to the Haskell Platform. I've been looking at the list posted at [0], and it turns out that GHC 7.10.2 doesn't bundle all the packages that are promised. (Or it's a case of PEBKAC and i apologise!) When i do `ghc-pkg list`, the output under ../package.conf.d provided by GHC notably has the following differences with the website list: $ diff website-list <(ghc-pkg list | ..prettify..) 2a3,4 10c12,14 < haddock --- 12,13c16 < old-locale < old-time --- 15a19 16a21 What surprises me is the lack of haddock, old-time and old-locale. Is this intentional, or a glitch on the website? I notice that these "missing" libraries are repeated in the `Additional Platform Libraries' and `Programs and Tools' sections. I guess this means that as a GHC packager, i should add these items separately? I guess what i'm saying is that i believe there is a bug in that list [0], but i'm not sure enough that i understand the
Categories: Offsite Discussion

Default definition for fromRational

libraries list - Thu, 10/15/2015 - 11:51pm
A suitable default definition for fromRational could be the following: fromRational n = fromInteger (numerator n) / fromInteger (denominator n) Changing the MINIMUM pragma to just {-# MINIMAL recip | (/) #-} - Joe
Categories: Offsite Discussion

Handling multiple fds with GHC

glasgow-user - Wed, 10/07/2015 - 8:49am
Hi, the last few days, I tried to get an IO-Event system running with GHC i.e. trigger an IO action when there is data to read from a fd. I looked at a few different implementations, but all of them have some downside. * using select package - This uses the select syscall. select is rather limited (fd cannot be * using GHC.Event - GHC.Event is broken in 7.10.1 (unless unsafeCoerce and a hacky trick are used) - GHC.Event is GHC internal according to hackage - Both Network libraries I looked at (networking (Network.Socket) and socket (System.Socket)) crash the application with GHC.Event - with 7.8+ I didn't see a way to create your own EventManager, so it only works with -threaded * using forkIO and threadWaitRead for each fd in a loop - needs some kind of custom control structure around it - uses a separate thread for each fd - might become pretty awkward to handle multiple events * using poll package - blocks in a safe foreign call - needs some kind of wrapper Fro
Categories: Offsite Discussion

using nmitchell's space leak detection technique

glasgow-user - Fri, 10/02/2015 - 3:02am
Neil Mitchell wrote an article about finding space leaks by limiting the stack size: http://neilmitchell.blogspot.fr/2015/09/detecting-space-leaks.html I'm giving it a try, but the results don't make any sense to me. My understanding is that the too-deep stack indicates that someone created too many thunks, so when they get evaluated you have to descend too many times. And if the stack trace seems to be a reasonable size (say 100 stack frames somehow consuming 1mb of stack) then it means there is a recursive call in there somewhere that ghc is helpfully eliding. And lastly, that the thing about "Stack space overflow: current size 33568 bytes." always showing 33568 bytes is due to a ghc bug and it should actually be whatever limit I gave it. Is all this accurate? The stack trace jumps around a lot, to places which are not lexically present in the caller. I assume this is just lazy evaluation, so e.g. maybe 'f' doesn't call 'g', but if 'f' forces a value returned from 'g' which has not yet been forced,
Categories: Offsite Discussion

New gtk2hs 0.12.4 release

gtk2hs - Wed, 11/21/2012 - 12:56pm

Thanks to John Lato and Duncan Coutts for the latest bugfix release! The latest packages should be buildable on GHC 7.6, and the cairo package should behave a bit nicer in ghci on Windows. Thanks to all!

~d

Categories: Incoming News