Closed gelisam closed 11 years ago
Ah, I was getting errors because I wasn't using OverloadedStrings, which I thought we were turning on by default. We are, but only for the user expression, not for the prelude! Which makes sense.
I tried to add it to my prelude, got an error, fixed a minor bug which was causing hawk to choke on pragmas, and now I'm trying to implement url
again.
My final hawk prelude is quite a bit longer than the sed solution, but at least now I have more experience creating a non-trivial prelude and thus a better understanding of the issues users might have using it. Closing.
{-# OPTIONS -XOverloadedStrings #-}
import Prelude
import qualified Data.ByteString.Lazy.Char8 as B
import Data.ByteString.Lazy.Char8 (ByteString)
import Data.Monoid
import Network.HTTP.Base
-- process the indented lines first, e.g.
-- > cat example.in
-- foo
-- bar
-- baz
-- quux
-- > cat example.in | hawk -l 'postorder (\x xs -> x <> "(" <> B.intercalate "," xs <> ")")'
-- foo(bar(baz()),quux())
postorder :: (ByteString -> [a] -> a) -> [ByteString] -> [a]
postorder call [] = []
postorder call (f:xs) = call f' ys
: postorder call xs'
where
n = indent f
f' = B.drop n f
ys = postorder call block
indent = B.length . B.takeWhile (==' ')
not_indented x = indent x <= n
(block, xs') = break not_indented xs
url :: [ByteString] -> ByteString
url (domain:xs) = domain <> "?" <> args xs
where
args :: [ByteString] -> ByteString
args = B.intercalate "&" . postorder encode . filter (B.any (/=' '))
encode :: ByteString -> [ByteString] -> ByteString
encode key = (key <>) . urlEncodeB . B.intercalate "&"
urlEncodeB :: ByteString -> ByteString
urlEncodeB = B.pack . urlEncode . B.unpack
Today at work I wanted to use hawk to solve the following problem, but I gave up. This issue is here to remind me to try that use case again at home and figure out whether it is hawk or me who was doing things wrong.
I had a file of the form
which I wanted to transform into
Where the indented subparams are joined with '&' before being url-encoded.
I eventually solved the problem with the pipeline
Which required a lot of trial and errors. I would like instead to solve it by adding something like the following function to the prelude and calling
hawk -l url
:But after much more trial-and-errors than it took me to implement the sed pipeline, I couldn't get the above definition to pass the typechecker.