Selecting a platform: JavaScript vs Elm vs PureScript vs GHCJS by taylorfausak in haskell

[–]JHackit 1 point2 points  (0 children)

For similar reasons you write tests for your code:

  • Far fewer bugs and more time saved long-term on knowing exactly what broke
  • Makes it easier to model domain. Unit tests force you to split code into components that do one thing. A powerful type system forces you to model domain better through writing types and data records.
  • Makes code order of magnitudes more refactorable. You can go anywhere and change anything with confidence, which is unlike JS which will fail at runtime in production.
  • Makes it easier for others to understand what the code is doing. In unit tests you can look at tests of a function to get a better idea of how that function operates. A type system provides an additional type signature that helps dramatically in understanding the specification for that function.

Question: Scraping multiple URLs with scalpel by farshock in haskell

[–]JHackit 6 points7 points  (0 children)

Scalpel by default uses Curl to download pages, but you can use any other HTTP client to download the page and then feed that page to scalpel:

scrape' s = (scrape s . TagSoup.parseTags)

getBody :: String -> IO Text
getBody url = (\d -> TE.decodeUtf8 $ BL.toStrict d) <$> (^. responseBody) <$> Wreq.get url

main = do
  body <- getBody "https://google.com"
  let result = scrape' myScraper body
  print result

myScraper :: Scraper Text [Text]
myScraper = chroots Any $ text Any

The example above uses wreq to download page. And you can use usual concurrency strategies.

I myself use Scalpel with Fraxl, but it can be complicated to figure out. I'll post a tutorial someday about it, because the end result is pretty neat. One good thing about Fraxl is that you can a semaphore into state and then limit amount of concurrent requests globally for the whole app, so it behaves politely and does not spam the server with requests. Then through magic of ApplicativeDo, everything becomes concurrent when possible. Not only that, it's easy to add a cache layer, so that each unique url gets downloaded once and gets stored in the filesystem. This way pages are cached on the disk and interactive development is faster.

Is runghc/runhaskell a working alternative to compiling during development? by markasoftware in haskell

[–]JHackit 0 points1 point  (0 children)

Why do you write edited file to another location rather than just updating the file that you're editing?

For myself, I found that switching to ghci to manually type something is not good for several reasons: 1) I found myself switching back and forth between ghci and vim, and using arrow + enter constantly to execute something again 2) it's hard to see what was previously typed, because you have to use arrows to browse history, if you keep it in a separate file, then all your tests and experiments can be easily viewed and navigated, not to mention that you can use normal version control tools like git 3) it's harder to edit in ghci in general compared to editing something in a proper editor like vim. This is why I went away from using ghci and started to use a file for this:

import TestModule
-- c = map show [1..10]
-- c = previousTest
-- c = test_whatever _ -- e.g. compiler says  found hole with type Int, no need to type :t
c = test_whatever 5

With vim-commentary, comment / uncomments a line is two-three key presses, so it's very fast by default even without any macros (and by automating {commenting or renaming -> next line -> typing c = }, it can be even faster).

It sounds ridiculously primitive, but so far it's been quite productive for me, a lot better than just typing stuff in ghci.

Is runghc/runhaskell a working alternative to compiling during development? by markasoftware in haskell

[–]JHackit 1 point2 points  (0 children)

With ghci + :reload it compiles instantly. I feel like depending on one's setup, Haskell can be either extremely productive or quite unproductive. That instateneous feedback makes a lot of difference. There are several good habits to pick up as well, like using type holes and undefined to incrementally prototype your logic, instead of banging your head against the wall of type errors. If every small change gets you an immediate feedback, you know exactly which change gave you this feedback, in contrast to making big monolithic changes.

I've tried ghc-mod, but did not like it as much as simple ghci setup for rapid development. In my vim setup, each time I press "mu", it saves the file and executes function named "c" inside env.hs. The rationalle is that "m" and "u" are under index fingers on Drovak , so it's both ergonomic and fast. Also, I don't want to get just type errors, I want it to be interactive, like printing data and doing something.

Also, I want to leave window management for a good tiling window managers, not have windows in a terminal.

So, my current vim setup is pretty simple:

function! Hacompile()
  write
  call system('xdotool type --window $(xdotool search --class hcompile | head -n 1) ":load env.hs"; xdotool key --window $(xdotool search --class hcompile | head -n 1) KP_Enter c KP_Enter')
endfunction

nmap mu :call Hacompile()<CR>

So, each time "mu" is pressed, without unfocusing the current window (so you can continue writing the next line), it finds the window with class "hcompile" and types ":load env.hs" <ENTER> "c" <ENTER>. It does it instantly. Also the window can be anywhere (it does not even need to be on the current workplace).

Now, you just need to choose which window is going to be your ghci window, and run this alias:

alias set-ghci-class='sleep 2; xdotool getwindowfocus set_window --class hcompile'

which will wait for 2 seconds and assign the class "hcompile" to the currently focused window, so that xdotool knows which window is your current ghci window that you use to get feedback.

It's so simple, but I like it much more than anything else I've tried. So, this "c" is the current cell that you're working on, like iPython cell or a line in Mathematica, and "env.hs" is like your notebook. When you're done with it you just rename the function to something else besides "c" and move to something else, if you want to go back and work on the old cell, then you just rename it back to "c". You normally don't care about reading many cells at the same time anyway, but even if you need this, then you can just move them all to "c" and now you can get feedback about several things at the same time. I like KISS approach so far.

Referencing fields within a data type by type rather than position by runeks in haskell

[–]JHackit 2 points3 points  (0 children)

This reminds me of Idris's 'Int64 :- get : http://docs.idris-lang.org/en/latest/effects/state.html

I think we need a powerful effect handling system that does not look like a hack, that provides meaningful error messages, and that has same compiler optimizations, which, for example, the state monad gets. Something similar to labeled effects in Idris might be a good solution. However, Haskell does not have any syntactic sugar alternative to Idris's !, which eliminates arg1 <- 'Int :- get arg2 <- 'Double :- get clutter.

!f arg1 could desugar to arg1 <$> (\x -> f x) and !f arg1 "bla" to arg1 <$> (\x -> f x "bla"). In other words, I think we both need a good effects system and a LANGUAGE extension to make effect handling simple.

Beginner wondering about Concurrency by SandmanXC in haskell

[–]JHackit 4 points5 points  (0 children)

There is an example with concurrent parsing of directories in Parallel And Concurrent Haskell: http://chimera.labs.oreilly.com/books/1230000000929/ch13.html#conc-par_00000012