News aggregator

Meet some problem when installing Agda

haskell-cafe - Sat, 05/02/2015 - 9:48pm
Hi I want to use Agda on my computer and I follow the instruction http://wiki.portal.chalmers.se/agda/pmwiki.php?n=Main.MacOSX However when I was using cabal install Agda to install agda, the terminal said The program cpphs version >=1.18.6 && <1.19 is required but the version found at /Users/XXXXXX/Library/Haskell/bin/cpphs is version 1.19 Do you have some idea how could i fix that problem? Zongzhe Yuan This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advis
Categories: Offsite Discussion

ANN: applicative-fail-1.0.0

haskell-cafe - Sat, 05/02/2015 - 9:32pm
Hi guys, here is reworked applicative-fail http://hackage.haskell.org/package/applicative-fail-1.0.0 You can use it to e.g. parse requests in your web application, or in any other parse-like stuff. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Start GHCI with a static library

haskell-cafe - Sat, 05/02/2015 - 4:24pm
Hi all, I have a Haskell library I'd like to load up in GHCI along with a statically linked C library (libblah.a) . Is there any way to do this? My Googling only turns up instructions on loading a shared library (libblah.so). Thanks! -deech _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Roman Cheplyaka: Smarter validation

Planet Haskell - Sat, 05/02/2015 - 2:00pm

Today we’ll explore different ways of handling and reporting errors in Haskell. We shall start with the well-known Either monad, proceed to a somewhat less common Validation applicative, and then improve its efficiency and user experience.

The article contains several exercises that will hopefully help you better understand the issues that are being addressed here.

Running example {-# LANGUAGE GeneralizedNewtypeDeriving, KindSignatures, DataKinds, ScopedTypeVariables, RankNTypes, DeriveFunctor #-} import Text.Printf import Text.Read import Control.Monad import Control.Applicative import Control.Applicative.Lift (Lift) import Control.Arrow (left) import Data.Functor.Constant (Constant) import Data.Monoid import Data.Traversable (sequenceA) import Data.List (intercalate, genericTake, genericLength) import Data.Proxy import System.Exit import System.IO import GHC.TypeLits

Our running example will consist of reading a list of integer numbers from a file, one number per line, and printing their sum.

Here’s the simplest way to do this in Haskell:

printSum1 :: FilePath -> IO () printSum1 path = print . sum . map read . lines =<< readFile path

This code works as expected for a well-formed file; however, if a line in the file can’t be parsed as a number, we’ll get unhelpful

Prelude.read: no parse Either monad

Let’s rewrite our function to be aware of possible errors.

parseNum :: Int -- line number (for error reporting) -> String -- line contents -> Either String Integer -- either parsed number or error message parseNum ln str = case readMaybe str of Just num -> Right num Nothing -> Left $ printf "Bad number on line %d: %s" ln str -- Print a message and exit die :: String -> IO () die msg = do hPutStrLn stderr msg exitFailure printSum2 :: FilePath -> IO () printSum2 path = either die print . liftM sum . sequence . zipWith parseNum [1..] . lines =<< readFile path

Now, upon reading a line that is not a number, we’d see something like

Bad number on line 2: foo

This is a rather standard usage of the Either monad, so I won’t get into details here. I’ll just note that there are two ways in which this version is different from the first one:

  1. We call readMaybe instead of read and, upon detecting an error, construct a helpful error message. For this reason, we keep track of the line number.
  2. Instead of throwing a runtime exception right away (using the error function), we return a pure Either value, and then combine these Eithers together using the Moand Either isntance.

The two changes are independent; there’s no reason why we couldn’t use error and get the same helpful error message. The exceptions emulated by the Either monad have the same semantics here as the runtime exceptions. The benefit of the pure formulation is that the semantics of runtime exceptions is built-in; but the semantics of the pure data is programmable, and we will take advantage of this fact below.

Validation applicative

You get a thousand-line file with numbers from your accountant. He asks you to sum them up because his enterprise software mysteriously crashes when trying to read it.

You accept the challenge, knowing that your Haskell program won’t let you down. The program tells you

Bad number on line 378: 12o0

— I see! Someone put o instead of zero. Let me fix it.

You locate the line 378 in your editor and replace 12o0 with 1200. Then you save the file, exit the editor, and re-run the program.

Bad number on line 380: 11i3

— Come on! There’s another similar mistake just two lines below. Except now 1 got replaced by i. If you told me about both errors from the beginning, I could fix them faster!

Indeed, there’s no reason why our program couldn’t try to parse every line in the file and tell us about all the mistakes at once.

Except now we can’t use the standard Monad and Applicative instances of Either. We need the Validation applicative.

The Validation applicative combines two Either values in such a way that, if they are both Left, their left values are combined with a monoidal operation. (In fact, even a Semigroup would suffice.) This allows us to collect errors from different lines.

newtype Validation e a = Validation { getValidation :: Either e a } deriving Functor instance Monoid e => Applicative (Validation e) where pure = Validation . Right Validation a <*> Validation b = Validation $ case a of Right va -> fmap va b Left ea -> either (Left . mappend ea) (const $ Left ea) b

The following example demonstrates the difference between the standard Applicative instance and the Validation one:

> let e1 = Left "error1"; e2 = Left " error2" > e1 *> e2 Left "error1" > getValidation $ Validation e1 *> Validation e2 Left "error1 error2"

A clever implementation of the same applicative functor exists inside the transformers package. Ross Paterson observes that this functor can be constructed as

type Errors e = Lift (Constant e)

(see Control.Applicative.Lift).

Anyway, let’s use this to improve our summing program.

printSum3 :: FilePath -> IO () printSum3 path = either (die . intercalate "\n") print . liftM sum . getValidation . sequenceA . map (Validation . left (\e -> [e])) . zipWith parseNum [1..] . lines =<< readFile path

Now a single invocation of the program shows all the errors it can find:

Bad number on line 378: 12o0 Bad number on line 380: 11i3

Exercise. Could we use Writer [String] to collect error messages?

Exercise. When appending lists, there is a danger of incurring quadratic complexity. Does that happen in the above function? Could it happen in a different function that uses the Validation applicative based on the list monoid?

Smarter Validation applicative

Next day your accountant sends you another thousand-line file to sum up. This time your terminal gets flooded by error messages:

Bad number on line 1: 27297. Bad number on line 2: 11986. Bad number on line 3: 18938. Bad number on line 4: 22820. ...

You already see the problem: every number ends with a dot. This is trivial to diagnose and fix, and there is absolutely no need to print a thousand error messages.

In fact, there are two different reasons to limit the number of reported errors:

  1. User experience: it is unlikely that the user will pay attention to more than, say, 10 messages at once. If we try to display too many errors on a web page, it may get slow and ugly.
  2. Efficiency: if we agree it’s only worth printing the first 10 errors, then, once we gather 10 errors, there is no point processing the data further.

Turns out, each of the two goals outlined above will need its own mechanism.

Bounded lists

We first develop a list-like datatype which stores only the first n elements and discards anything else that may get appended. This primarily addresses our first goal, user experience, although it will be handy for achieving the second goal too.

Although for validation purposes we may settle with the limit of 10, it’s nice to make this a generic, reusable type with a flexible limit. So we’ll make the limit a part of the type, taking advantage of the type-level number literals.

Exercise. Think of the alternatives to storing the limit in the type. What are their pros and cons?

On the value level, we will base the new type on difference lists, to avoid the quadratic complexity issue that I allude to above.

data BoundedList (n :: Nat) a = BoundedList !Integer -- current length of the list (Endo [a])

Exercise. Why is it important to cache the current length instead of computing it from the difference list?

Once we’ve figured out the main ideas (encoding the limit in the type, using difference lists, caching the current length), the actual implementation is straightforward.

singleton :: KnownNat n => a -> BoundedList n a singleton a = fromList [a] toList :: BoundedList n a -> [a] toList (BoundedList _ (Endo f)) = f [] fromList :: forall a n . KnownNat n => [a] -> BoundedList n a fromList lst = BoundedList (min len limit) (Endo (genericTake limit lst ++)) where limit = natVal (Proxy :: Proxy n) len = genericLength lst instance KnownNat n => Monoid (BoundedList n a) where mempty = BoundedList 0 mempty mappend b1@(BoundedList l1 f1) (BoundedList l2 f2) | l1 >= limit = b1 | l1 + l2 <= limit = BoundedList (l1 + l2) (f1 <> f2) | otherwise = BoundedList limit (f1 <> Endo (genericTake (limit - l1)) <> f2) where limit = natVal (Proxy :: Proxy n) full :: forall a n . KnownNat n => BoundedList n a -> Bool full (BoundedList l _) = l >= natVal (Proxy :: Proxy n) null :: BoundedList n a -> Bool null (BoundedList l _) = l <= 0 SmartValidation

Now we will build the smart validation applicative which stops doing work when it doesn’t make sense to collect errors further anymore. This is a balance between the Either applicative, which can only store a single error, and Validation, which collects all of them.

Implementing such an applicative functor is not as trivial as it may appear at first. In fact, before reading the code below, I recommend doing the following

Exercise. Try implementing a type and an applicative instance for it which adheres to the above specification.

Did you try it? Did you succeed? This is not a rhetorical question, I am actually interested, so let me know. Is your implementation the same as mine, or is it simpler, or more complicated?

Alright, here’s my implementation.

newtype SmartValidation (n :: Nat) e a = SmartValidation { getSmartValidation :: forall r . Either (BoundedList n e) (a -> r) -> Either (BoundedList n e) r } deriving Functor instance KnownNat n => Applicative (SmartValidation n e) where pure x = SmartValidation $ \k -> k <*> Right x SmartValidation a <*> SmartValidation b = SmartValidation $ \k -> let k' = fmap (.) k in case a k' of Left errs | full errs -> Left errs r -> b r

And here are some functions to construct and analyze SmartValidation values.

-- Convert SmartValidation to Either fatal :: SmartValidation n e a -> Either [e] a fatal = left toList . ($ Right id) . getSmartValidation -- Convert Either to SmartValidation nonFatal :: KnownNat n => Either e a -> SmartValidation n e a nonFatal a = SmartValidation $ (\k -> k <+> left singleton a) -- like <*>, but mappends the errors (<+>) :: Monoid e => Either e (a -> b) -> Either e a -> Either e b a <+> b = case (a,b) of (Right va, Right vb) -> Right $ va vb (Left e, Right _) -> Left e (Right _, Left e) -> Left e (Left e1, Left e2) -> Left $ e1 <> e2

Exercise. Work out what fmap (.) k does in the definition of <*>.

Exercise. In the definition of <*>, should we check whether k is full before evaluating a k'?

Exercise. We developed two mechanisms — BoundedList and SmartValidation, which seem to do about the same thing on different levels. Would any one of these two mechanisms suffice to achieve both our goals, user experience and efficiency, when there are many errors being reported?

Exercise. If the SmartValidation applicative was based on ordinary lists instead of difference lists, would we be less or more likely to run into the quadratic complexity problem compared to simple Validation?

Conclusion

Although the Validation applicative is known among Haskellers, the need to limit the number of errors it produces is rarely (if ever) discussed. Implementing an applicative functor that limits the number of errors and avoids doing extra work is somewhat tricky. Thus, I am happy to share my solution and curious about how other people have dealt with this problem.

Categories: Offsite Blogs

Strongly-typed ghci commands

Haskell on Reddit - Sat, 05/02/2015 - 1:56pm
Categories: Incoming News

Parsing YAML with varying structure

haskell-cafe - Sat, 05/02/2015 - 1:55pm
Dear Cafe, I need help parsing YAML files with varying structure. The minimal example is: a yaml file that has one key, which can hold either one key-value pair or two key value pairs. I have data types for the one key, and the two possible sub-keys: To read MyList and Item from the file I wrote FromJSON instances I also have read functions for MyList and Item: The file test.yaml looks like or, alternatively The question is how I can decode test.yaml to get Var. Trying to code readVar like readItem (having FromJSON Var like FromJSON Item) failed. For convenience I attached the relevant source files. Regards, Johannes. _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Smarter validation

Haskell on Reddit - Sat, 05/02/2015 - 12:29pm
Categories: Incoming News

Has someone got an test/spec version of Haskell 99 problems ?

Haskell on Reddit - Sat, 05/02/2015 - 11:48am

I though whilst waiting for things to compiles, I could give Haskell 99 problems a go. I was wondering : has someone a "spec", or better a, doctest version ready to use, so you just have to run the test and fillin the blanks ?

submitted by maxigit
[link] [2 comments]
Categories: Incoming News

PSA: How to use the cabal-version field in cabalfiles

haskell-cafe - Sat, 05/02/2015 - 9:31am
The cabal-version field seems pretty mysterious. Recommendation: Set it no higher than >= 1.10, Cabal will warn you if it's too low. This field contains the format of the cabal file, the number corresponds to the Cabal release. Hence this version is incremented more often than the format actually changes. There have been no significant changes between 1.10 and 1.20. The Cabal source is surprisingly helpful as a changelog: https://github.com/haskell/cabal/blob/641e854ae663e2b34f34ecc11ba663ac3a9bdc19/Cabal/Distribution/PackageDescription/Check.hs#L911-L1091 By setting it too high you risk users getting errors like "The package 'foo' requires Cabal library version -any && >=1.14 but no suitable version is installed." This can be problematic for anyone using an older GHC or if there are Cabal releases outside of the GHC release cycle. You may get this error even if you have a newer Cabal if it doesn't ship with GHC. Happy hacking, Adam _______________________________________________ Haskell-Cafe mailing li
Categories: Offsite Discussion

Binary vs Aeson interface

Haskell on Reddit - Sat, 05/02/2015 - 7:12am

Is there a reason that Aeson recommends against using deriving Generic and instead recommends their Template Haskell interface while Binary happily uses deriving Generic and doesn't even have a TH interface?

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

People using Haskell in production: what is your build/deployment setup?

Haskell on Reddit - Sat, 05/02/2015 - 5:33am

I use Haskell for personal experimentation, but I am now starting a "real" project, deploying Haskell programs and dependencies to public servers. I have very little experience doing this in Haskell-land.

What do you (or your company) use? Here's a non-exhaustive list of things I'd like to hear about:

  • I guess everyone uses Cabal?
  • Do you deploy to bare metal, or VMs, or some "container" solution, or ..?
  • Do you use externally-hosted machines, e.g. AWS or Heroku?
  • Do you use Nix? Do you use cabal2nix? Do you use NixOS? Do you use NixOps? Do you use Disnix?
  • Do you provision machines with e.g. Puppet?
  • Are you able to reproduce your production environment locally? What do you use for that?
  • Do you have a CI server? What compiles the binaries you put into production? Do you build them locally?
  • Do you build big statically linked binaries? Does this work?
  • Are you able to build and deploy with git push or similar? Is this desirable?
  • Do you use framework-specific deployment tools like Keter (for Yesod)?

What works, and what doesn't? What things (e.g. NixOps) have momentum and active support? Are there Haskell-specific pitfalls to avoid?

EDIT: Thanks everyone for your input! Here's an informal, subjective summary of your responses.

  • In most respects, deploying Haskell isn't that different to deploying anything else! This is good news! All the following choices are orthogonal to choosing whether to use Haskell, and there are no obvious pitfalls to any of them, so choose whatever you're comfortable with:

    • Hosting (AWS/DO/Linode/etc)
    • Operating system (Ubuntu/CoreOS/Windows(!))
    • Provisioning (Puppet/Chef/Ansible/Propellor)
    • CI (Hydra/Bake/Jenkins/GitLabCI/Travis/Buildbot/CircleCI/etc).
  • Cabal is indeed used universally. Some people are also using Shake for more complex builds.

  • Stackage is very popular. Presumably meaning a lot of people have been bitten by 'Cabal Hell'.

  • Nix hasn't caught on in the Haskell community as much as I had expected (based on Hackage mentioning NixOS all the time). However, a lot of people have eyes on it, and /u/ocharles appears to have adopted it wholesale and is quite evangelistic. :-)

  • The main deployment strategies people are using are:

    • A very simple setup: build static binaries locally, scp/rsync to server, and restart with a process monitor. Many people are using Keter as a process monitor (+ other features).
    • Containerization; mostly using Docker. There are many varieties on this strategy.
    • Halcyon. I hadn't heard of it before now, but I see many recommendations! (I must confess I'm still slightly in the dark on what it does/doesn't do.)
submitted by Jameshfisher
[link] [63 comments]
Categories: Incoming News

Better implementation of Show instance for Data.Scientific

libraries list - Sat, 05/02/2015 - 5:02am
Hi there, Data.Scientific just introduced a new implementation of Show instance to display "integers" without radix point or fractional part and display "real numbers" more nicely. While I do like the new formated output, the implementation seems overkill and scared me, so I commented my thought on github: https://github.com/basvandijk/scientific/commit/9f6cbe9192d88becb7dcf3dbce3b6018ba21d9ca Now, I post here to ask for people's opinion on this as suggested by Bas van Dijk. Thanks.
Categories: Offsite Discussion

Containers and the Monoid relation to Foldable

Haskell on Reddit - Sat, 05/02/2015 - 2:47am

Is it reasonable to assume the following for any instance of both Foldable and Monoid?

  • mempty <=> null
  • x /= mempty <=> not . null

where null is Data.Foldable.null.

Is there some type for which this does not hold?

Writing collection agnostic code in Haskell can sometimes be awkward since there is no type class for collections. Instead one may have to combine methods from different type classes and that is scary because we don't have laws on how they are supposed to be related (?).

Some things to consider:

  • How to check if a container is empty. One could either compare to mempty (and thus adding an Eq constraint to the contained value type) or apply the polymorphic null, which has recenty been added to Foldable.

  • How to produce an empty container. I think mempty is the only way to do this now.

  • How to produce a container with a singleton value. One could use return or even pure, but Applicative and Monad are awkward constraints to put on a container.

  • How to add an element to a container. The only way now seem to involve creating a singleton (see above) and combine with the rest of the collection using mappend.

Any thoughts on this?

submitted by togrof
[link] [10 comments]
Categories: Incoming News

Import hiding module

haskell-cafe - Sat, 05/02/2015 - 1:10am
It's possible to write e.g. module A (module A.B, x) where To reexport everything from A.B And we can import A hiding (x) Is there a way to also import A hiding (module A.B) ? Thanks
Categories: Offsite Discussion

Edward Z. Yang: Width-adaptive XMonad layout

Planet Haskell - Fri, 05/01/2015 - 10:36pm

My usual laptop setup is I have a wide monitor, and then I use my laptop screen as a secondary monitor. For a long time, I had two XMonad layouts: one full screen layout for my laptop monitor (I use big fonts to go easy on the eyes) and a two-column layout when I'm on the big screen.

But I had an irritating problem: if I switched a workspace from the small screen to the big screen, XMonad would still be using the full screen layout, and I would have to Alt-Tab my way into the two column layout. To add insult to injury, if I moved it back, I'd have to Alt-Tab once again.

After badgering the fine folks on #xmonad, I finally wrote an extension to automatically switch layout based on screen size! Here it is:

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-} ----------------------------------------------------------------------------- -- | -- Module : XMonad.Layout.PerScreen -- Copyright : (c) Edward Z. Yang -- License : BSD-style (see LICENSE) -- -- Maintainer : <ezyang@cs.stanford.edu> -- Stability : unstable -- Portability : unportable -- -- Configure layouts based on the width of your screen; use your -- favorite multi-column layout for wide screens and a full-screen -- layout for small ones. ----------------------------------------------------------------------------- module XMonad.Layout.PerScreen ( -- * Usage -- $usage PerScreen, ifWider ) where import XMonad import qualified XMonad.StackSet as W import Data.Maybe (fromMaybe) -- $usage -- You can use this module by importing it into your ~\/.xmonad\/xmonad.hs file: -- -- > import XMonad.Layout.PerScreen -- -- and modifying your layoutHook as follows (for example): -- -- > layoutHook = ifWider 1280 (Tall 1 (3/100) (1/2) ||| Full) Full -- -- Replace any of the layouts with any arbitrarily complicated layout. -- ifWider can also be used inside other layout combinators. ifWider :: (LayoutClass l1 a, LayoutClass l2 a) => Dimension -- ^ target screen width -> (l1 a) -- ^ layout to use when the screen is wide enough -> (l2 a) -- ^ layout to use otherwise -> PerScreen l1 l2 a ifWider w = PerScreen w False data PerScreen l1 l2 a = PerScreen Dimension Bool (l1 a) (l2 a) deriving (Read, Show) -- | Construct new PerScreen values with possibly modified layouts. mkNewPerScreenT :: PerScreen l1 l2 a -> Maybe (l1 a) -> PerScreen l1 l2 a mkNewPerScreenT (PerScreen w _ lt lf) mlt' = (\lt' -> PerScreen w True lt' lf) $ fromMaybe lt mlt' mkNewPerScreenF :: PerScreen l1 l2 a -> Maybe (l2 a) -> PerScreen l1 l2 a mkNewPerScreenF (PerScreen w _ lt lf) mlf' = (\lf' -> PerScreen w False lt lf') $ fromMaybe lf mlf' instance (LayoutClass l1 a, LayoutClass l2 a, Show a) => LayoutClass (PerScreen l1 l2) a where runLayout (W.Workspace i p@(PerScreen w _ lt lf) ms) r | rect_width r > w = do (wrs, mlt') <- runLayout (W.Workspace i lt ms) r return (wrs, Just $ mkNewPerScreenT p mlt') | otherwise = do (wrs, mlt') <- runLayout (W.Workspace i lf ms) r return (wrs, Just $ mkNewPerScreenF p mlt') handleMessage (PerScreen w bool lt lf) m | bool = handleMessage lt m >>= maybe (return Nothing) (\nt -> return . Just $ PerScreen w bool nt lf) | otherwise = handleMessage lf m >>= maybe (return Nothing) (\nf -> return . Just $ PerScreen w bool lt nf) description (PerScreen _ True l1 _) = description l1 description (PerScreen _ _ _ l2) = description l2

I'm going to submit it to xmonad-contrib, if I can figure out their darn patch submission process...

Categories: Offsite Blogs