Ported a Python script for use with Go to Haskell

It's been 3 years since my last attempt to use Haskell. I've ported a script from Python, I wonder if anyone might point out areas that I'm not doing things idiomatically for Haskell? I'm hoping to start using Haskell more in place of Go and Python. The Haskell script: http://pastebin.com/SxH3PXgG The original Python script if you're curious: http://pastebin.com/bqUVxB5d

On Apr 5, 2014, at 8:32 , Matt Joiner
It's been 3 years since my last attempt to use Haskell. I've ported a script from Python, I wonder if anyone might point out areas that I'm not doing things idiomatically for Haskell? I'm hoping to start using Haskell more in place of Go and Python.
Hardly an expert here, but a couple of remarks: - try using ‘span’ (Prelude) for splitting the argument list - clobbering the environment by prepending to an association list makes me wonder if that’s really what happens when the variable is already defined - 'fmap rstrip (readProcess …)’ or ‘rstrip <$> readProcess …’ instead of ‘readProcess … >>= return . rstrip’ It does look like Haskell to my eyes. Cheers Rob

Thanks very much. I'll look into fmap and <$>.
On 05/04/2014 9:21 pm, "Robert Vollmert"
It's been 3 years since my last attempt to use Haskell. I've ported a
On Apr 5, 2014, at 8:32 , Matt Joiner
wrote: script from Python, I wonder if anyone might point out areas that I'm not doing things idiomatically for Haskell? I'm hoping to start using Haskell more in place of Go and Python. Hardly an expert here, but a couple of remarks:
- try using ‘span’ (Prelude) for splitting the argument list - clobbering the environment by prepending to an association list makes me wonder if that’s really what happens when the variable is already defined - 'fmap rstrip (readProcess …)’ or ‘rstrip <$> readProcess …’ instead of ‘readProcess … >>= return . rstrip’
It does look like Haskell to my eyes.
Cheers Rob

On Sat, Apr 5, 2014 at 5:21 PM, Robert Vollmert
- clobbering the environment by prepending to an association list makes me wonder if that's really what happens when the variable is already defined
Yes, that does raise flags. The haskell here: installEnv <- getEnvironment >>= return . (:) ("GOBIN", gOBIN) which I'd probably write as installEnv <- (("GOBIN", gOBIN) :) <$> getEnvironment doesn't match the python here: GOBIN = tempfile.gettempdir() os.environ['GOBIN'] = GOBIN in the sense that the case for a predefined GOBIN in the environment will lead to different results. At least I'll be surprised if otherwise. To Matt: have you tested your haskell version? You might want to take a look at System.Posix.Env.putenv. -- Kim-Ee

The script itself looks pretty good to me, but you might want to take a
look at Shelly https://hackage.haskell.org/package/shelly [0] for Haskell
scripting in the future. It's a really nice library / DSL for "bash"-like
scripting directly in Haskell. If you try out Shelly, I suggest trying it
with ClassyPrelude and -XOverloadedStrings, which makes dealing with all
the Text and FilePath types bearable. (Heh, though it's annoying, having
FilePath as a separate type once prevented me from writing code that
deleted my home directory upon being run... fun story.)
[0] https://hackage.haskell.org/package/shelly
On Sat, Apr 5, 2014 at 4:33 AM, Kim-Ee Yeoh
On Sat, Apr 5, 2014 at 5:21 PM, Robert Vollmert
wrote: - clobbering the environment by prepending to an association list makes me wonder if that's really what happens when the variable is already defined
Yes, that does raise flags.
The haskell here:
installEnv <- getEnvironment >>= return . (:) ("GOBIN", gOBIN)
which I'd probably write as
installEnv <- (("GOBIN", gOBIN) :) <$> getEnvironment
doesn't match the python here:
GOBIN = tempfile.gettempdir() os.environ['GOBIN'] = GOBIN
in the sense that the case for a predefined GOBIN in the environment will lead to different results. At least I'll be surprised if otherwise.
To Matt: have you tested your haskell version? You might want to take a look at System.Posix.Env.putenv.
-- Kim-Ee
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

I considered the same thing with an existing GOBIN env var. I did actually
test it and found it worked as expected. Items earlier in the list seem to
have higher priority. I prefer not to use setenv, because I want to exec
into the binary later without GOBIN clobbered, which means keeping the
current environment pristine. Good point about it not matching the Python
version, but then a few other things don't either now. :)
Here's the latest version: http://pastebin.com/EejABjpR
Something I can't get my head around: On line 50-52, I have a function that
returns the result of getting the current directory (curDir) joined with
the package path (maybeToList package). Is there someway to get the current
directory without having to store the action the way that I am doing? <$>
would work if the current directory was the last argument to the joinPath,
but here it's the first.
Thanks so much for your help.
On Sun, Apr 6, 2014 at 2:48 AM, Andrew Gibiansky wrote: The script itself looks pretty good to me, but you might want to take a
look at Shelly https://hackage.haskell.org/package/shelly [0] for
Haskell scripting in the future. It's a really nice library / DSL for
"bash"-like scripting directly in Haskell. If you try out Shelly, I suggest
trying it with ClassyPrelude and -XOverloadedStrings, which makes dealing
with all the Text and FilePath types bearable. (Heh, though it's annoying,
having FilePath as a separate type once prevented me from writing code that
deleted my home directory upon being run... fun story.) [0] https://hackage.haskell.org/package/shelly On Sat, Apr 5, 2014 at 4:33 AM, Kim-Ee Yeoh On Sat, Apr 5, 2014 at 5:21 PM, Robert Vollmert - clobbering the environment by prepending to an association list makes
me wonder if that’s really what happens when the variable is already defined Yes, that does raise flags. The haskell here: installEnv <- getEnvironment >>= return . (:) ("GOBIN", gOBIN) which I'd probably write as installEnv <- (("GOBIN", gOBIN) :) <$> getEnvironment doesn't match the python here: GOBIN = tempfile.gettempdir()
os.environ['GOBIN'] = GOBIN in the sense that the case for a predefined GOBIN in the environment will
lead to different results. At least I'll be surprised if otherwise. To Matt: have you tested your haskell version? You might want to take a
look at System.Posix.Env.putenv. -- Kim-Ee _______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

On Sat, Apr 5, 2014 at 11:17 PM, Matt Joiner
I considered the same thing with an existing GOBIN env var. I did actually test it and found it worked as expected.
Omg, color me surprised!
Items earlier in the list seem to have higher priority.
I'd drill deeper into this to find out why if I had the time, but in any case, are you sure you want to rely on such brittle, undocumented behavior? Goerzen's MissingH has an addToAL that's perfect for the job: origEnv <- getEnvironment let clobberedEnv = addToAL origEnv "GOBIN" dest I prefer not to use setenv, because I want to exec into the binary later
without GOBIN clobbered, which means keeping the current environment pristine. Good point about it not matching the Python version, but then a few other things don't either now. :)
Fair enough. :) -- Kim-Ee
participants (4)
-
Andrew Gibiansky
-
Kim-Ee Yeoh
-
Matt Joiner
-
Robert Vollmert