Is there identity conduit? - haskell

The title says it all. I've seen that some people apparently use Data.Conduit.List.map id as identity conduit, but is this the recommended way to stream data unchanged?

The simplest way to write an identity conduit is probably:
awaitForever yield
because this doesn't require an extra import.
The definition of Data.Conduit.List.map is very similar:
mapC f = awaitForever $ yield . f
(The difference between mapC and map has something to do with CPP macros to define fusion.)
When optimization is on (-O1), it appears both options result in identical code, so it's just a matter of taste.

Related

how to see the implemented code of a function of a module in haskell?

I am a newbie to Haskell and I know The Haskell standard library is split into modules, each of them contains functions and types that are somehow related and serve some common purpose. I would like to see the implementation(code) of those library functions.where can I see that ? is there any command in ghci so that I can see the implementation or provide me any resources to learn about modules.
Thank you
Probably the most convenient way to do it, is use Hackage. You can for instance inspect the map function, by clicking Source on the right side of the function signature. This then will show the highlighted code fragment. For instance:
map :: (a -> b) -> [a] -> [b]
{-# NOINLINE [0] map #-}
-- We want the RULEs "map" and "map/coerce" to fire first.
-- map is recursive, so won't inline anyway,
-- but saying so is more explicit, and silences warnings
map _ [] = []
map f (x:xs) = f x : map f xs
You can also use Hoogle to search functions by name or signature, and by clicking the results, you will be redirected to the relevant hackage page.

Safely serialize Text to Bytestring

The text package does not provide an instance of Binary to encode/decode text. I have read about and understand the reasoning behind this (namely, Text should be encoding-agnostic). However, I need a Binary instance of Text. I've found that there is a package called text-binary that does this. However, the instance is as follows:
instance Binary T.Text where
put = put . T.encodeUtf8
get = T.decodeUtf8 <$> get
Pretty good, except that decodeUtf8 is a partial function, so I'd rather be using decodeUtf8' and passing the failure through the Get monad. I can't figure out how to fail correctly with the Get monad. Just from looking around in Data.Binary.Get, I see this:
data Decoder a = Fail !B.ByteString {-# UNPACK #-} !ByteOffset String
| Partial (Maybe B.ByteString -> Decoder a)
| Done !B.ByteString {-# UNPACK #-} !ByteOffset a
Which seems to indicate that there is a way to do what I want. I just can't see how the library authors intend for it to be used. I appreciate any insights that a more learned mind than my own has to offer.
Well, though we tend to disregard it, the Monad class still has that yucky fail method:
get = do
utf8'd <- get
case T.decodeUtf8' utf8'd of
Just t -> return t
Nothing -> fail "No parse for UTF-8 Text"
I'm not sure if it should still be considered "correct" to use fail, but it seems to be the obvious thing for a case like this. I suppose even if it's removed from the Monad class, there'll be some other class MonadPlus m => MonadFail m where fail :: String -> m a which Get will be an instance of.

Alpha conversion on a Haskell expression

Given a Haskell expression, I'd like to perform alpha conversion, ie. rename some of the non free variables.
I've started implementing my own function for this, which works on a haskell-src-exts Exp tree, however it turns out to be surprisingly nontrivial, so I can't help wondering - is there an established easy-to-use library solution for this kind of source conversion? Ideally, it should integrate with haskell-src-exts.
This is one of the problems where the "Scrap Your Boilerplate" style generic libraries shine!
The one I'm most familiar with is the uniplate package, but I don't actually have it installed at the moment, so I'll use the (very similar) functionality found in the lens package. The idea here is that it uses Data.Data.Data (which is the best qualified name ever) and related classes to perform generic operations in a polymorphic way.
Here's the simplest possible example:
alphaConvert :: Module -> Module
alphaConvert = template %~ changeName
changeName :: Name -> Name
changeName (Ident n) = Ident $ n ++ "_conv"
changeName n = n
The (%~) operator is from lens and just means to to apply the function changeName to everything selected by the generic traversal template. So what this does is find every alphanumeric identifier and append _conv to it. Running this program on its own source produces this:
module AlphaConv where
import Language.Haskell.Exts
import Control.Lens
import Control.Lens.Plated
import Data.Data.Lens
instance Plated_conv Module_conv
main_conv
= do ParseOk_conv md_conv <- parseFile_conv "AlphaConv.hs"
putStrLn_conv $ prettyPrint_conv md_conv
let md'_conv = alphaConvert_conv md_conv
putStrLn_conv $ prettyPrint_conv md'_conv
alphaConvert_conv :: Module_conv -> Module_conv
alphaConvert_conv = template_conv %~ changeName_conv
changeName_conv :: Name_conv -> Name_conv
changeName_conv (Ident_conv n_conv)
= Ident_conv $ n_conv ++ "_conv"
changeName_conv n_conv = n_conv
Not terribly useful since it doesn't distinguish between identifiers bound locally and those defined in an outside scope (such as being imported), but it demonstrates the basic idea.
lens may seem a bit intimidating (it has a lot more functionality than just this); you may find uniplate or another library more approachable.
The way you'd approach your actual problem would be a multi-part transformation that first selects the subexpressions you want to alpha-convert inside of, then uses a transformation on those to modify the names you want changed.

Which Monad do I need?

This is something of an extension to this question:
Dispatching to correct function with command line arguments in Haskell
So, as it turns out, I don't have a good solution yet for dispatching "commands" from the command line to other functions. So, I'd like to extend the approach in the question above. It seems cumbersome to have to manually add functions to the table and apply the appropriate transformation function to each function so that it takes a list of the correct size instead of its normal arguments. Instead, I'd like to build a table where I'll add functions and "tag" them with the number of arguments it needs to take from the command line. The "add" procedure, should then take care of composing with the correct "takesXarguments" procedure and adding it to the table.
I'd like to be able to install "packages" of functions into the table, which makes me think I need to be able to keep track of the state of the table, since it will change when packages get installed. Is the Reader Monad or the State Monad what I'm looking for?
No monad necessary. Your tagging idea is on the right track, but that information is encoded probably in a different way than you expected.
I would start with a definition of a command:
type Command = [String] -> IO ()
Then you can make "command maker" functions:
mkCommand1 :: (String -> IO ()) -> Command
mkCommand2 :: (String -> String -> IO ()) -> Command
...
Which serves as the tag. If you don't like the proliferation of functions, you can also make a "command lambda":
arg :: (String -> Command) -> Command
arg f (x:xs) = f x xs
arg f [] = fail "Wrong number of arguments"
So that you can write commands like:
printHelloName :: Command
printHelloName = arg $ \first -> arg $ \last -> do
putStrLn $ "Hello, Mr(s). " ++ last
putStrLn $ "May I call you " ++ first ++ "?"
Of course mkCommand1 etc. can be easily written in terms of arg, for the best of both worlds.
As for packages, Command sufficiently encapsulates choices between multiple subcommands, but they don't compose. One option here is to change Command to:
type Command = [String] -> Maybe (IO ())
Which allows you to compose multiple Commands into a single one by taking the first action that does not return Nothing. Now your packages are just values of type Command as well. (In general with Haskell we are very interested in these compositions -- rather than packages and lists, think about how you can take two of some object to make a composite object)
To save you from the desire you have surely built up: (1) there is no reasonable way to detect the number of arguments a function takes*, and (2) there is no way to make a type depend on a number, so you won't be able to create a mkCommand which takes as its first argument an Int for the number of arguments.
Hope this helped.
In this case, it turns out that there is, but I recommend against it and think it is a bad habit -- when things get more abstract the technique breaks down. But I'm something of a purist; the more duct-tapey Haskellers might disagree with me.

Haskell: Conditionally execute external process with Maybe FilePath

I am struggling to understand a block of code which is extremely easy in imperative world.
That's what I need to do: given an executable full path, which is a Maybe FilePath type, I need to execute it conditionally.
If the path is a Nothing - print an error, if the path is Just Path - execute it and print message that the file has been executed. Only "Hello, World" can be easier,right?
But in Haskell I dug my self into numerous layers of Maybe's and IO's and got stuck.
Two concrete questions arise from here:
How do I feed a Maybe FilePath into a system or rawSystem? liftM does not work for me here.
What is the correct way of doing this kind of conditional branching?
Thanks.
Simple pattern matching will do the job nicely.
case command of
Just path -> system path >> putStrLn "Done"
Nothing -> putStrLn "None specified"
Or, if you'd rather not pattern-match, use the maybe function:
maybe (putStrLn "None specified") ((>> putStrLn "Done") . system) command
That may occasionally be nicer than matching with a case, but not here, I think. The composition with the printing of the success message is clunky. It fares better if you don't print messages but return the ExitCode in both branches:
maybe (return $ ExitFailure 1) system command
This is exactly what the Traversable type class was made for!
Prelude Data.Traversable System.Cmd> traverse system Nothing
Nothing
Prelude Data.Traversable System.Cmd> traverse system (Just "echo OMG BEES")
OMG BEES
Just ExitSuccess

Resources