Is there any way to extend library module in Haskell?
For example, I would like to add firstToLower function to Data.String. When I create my own Data.String it masks library one:
module Data.String where
import Prelude
import Data.Char (toLower)
firstToLower :: String -> String
firstToLower (c:cs) = toLower c : cs
firstToLower "" = ""
Then I get error trying to import Data.String (lines):
Module `Data.String' does not export `lines'
It would be really nice if such thing is possible. If not, what are best practices for such situations? Where such extensions should be placed?
Thank you.
Update
I don't plan to release my extensions as a library, just want to organize it inside my project in a meaningful way.
No, this is not possible. One solution that people have used in the past is to put your additions in a module with a name like Data.String.Extra and release that module on Hackage (if you think that your additions could be useful to other people).
Alternatively, you can propose your extension for inclusion in the standard library.
Related
I'm trying to use Format library and the fmt function. I'm getting the error Variable not in scope: fmt :: t1 -> Text.
I'm trying to find the correct import module but can't seem to get it right. I've followed this https://hackage.haskell.org/package/fmt-0.6.3.0/docs/Fmt.html, and I have added {-# LANGUAGE OverloadedStrings #-} and import Fmt at the top of my module, but then get Could not find module ‘Fmt’
The function I'm using is:
--This uses the Format library and the fmt function. It is a formatting library. in this case it attaches a name (msg) to a list(of Text), line by line.
allWordsReport :: String -> [Text] -> Text
allWordsReport msg words =
fmt $ nameF (fromString msg) $ unlinesF words
I'm struggling with the imports a lot for Haskell. Is there an easy way to find what I need to use, as it seems to be more difficult to find documentation for stuff than other languages.
Are you using stack, cabal or other as your build environment? If you are using cabal primarily, one issue might be not having the library installed in the way GHC needs it. Since I am not building production code and just use Haskell to learn programming concepts, I only use cabal and only have one environment. So for me, I did the below to get it working.
cabal install fmt --lib
If you are do things correctly for packaging, then, as noted by Sridhar, you should use dependency information in cabal or stack configuration files.
I am new to Haskell, I am thinking to do a small project of processing the spreadsheet data to improve my Haskell. However I don't know how to import the module needed which is the Data.List.Split so that I can split the data.
Not sure if import like this is correct, I am not using cabal but stack.
I added the extra-deps : [split-0.2.3.4] in my .yaml file but still it does not work, it still show could not find Data.List.Split module.
Thank you.
Here is the error I get
I finally solved it. Simply add "- split == 0.2.3.4" in the package.yaml file "dependencies:" section. Then do the repl again by using "stack ghci" in the command prompt.
Now I am able to use the splitOn function from the Data.List.Split module.
I am learning about Haskell. I am importing the Options.Applicative module, like so:
import Options.Applicative ((<>), Parser)
import qualified Options.Applicative as P
However, this returns
Module ‘Options.Applicative’ does not export ‘(<>)’
What is wrong with this? This documentation suggests this should be possible.
You need to import (<>) from either Data.Monoid or Data.Semigroup, as Options.Applicative doesn't actually re-export it. A quick way to verify that is checking the "<" page in the documentation index, which would include (<>) if it was re-exported.
P.S.: While the readme currently on Hackage is slightly misleading indeed, the missing import was already added upstream at GitHub, and so it will be fixed when the next version of the package is released.
(<>) is in Data.Monoid, not Options.Applicative. It's an infix synonym for mappend.
I want to add an helper function to my yesod app that will "live" in a seperate file and could be imported in both foundation file and the handlers, i dont want to have reimport all the modules again. and i cant use the Import module because im getting circular dependencies ( Import -> helper -> foundation -> Import).
The GHC manual has a section on mutually recursive modules.
I think rather than messing around with mutually-recursive modules it might be better to just re-import all the stuff from Import that you want.
I have a Haskell module, and I’d like it to export all objects declared in its file except for one specific function local_func.
Is there a cleaner way to achieve this than by writing an export list explicitly listing all the other declarations (and carefully keeping this list up-to-date for all eternity)?
In other words, I’d like an analogue of import MyModule hiding (local_func), but specified in the exporting module rather that at import time.
As far as I'm aware there is not currently a way to do this.
What I usually end up doing is having a central module that re-exports important things as a convenient way to import everything that is necessary while not hiding anything in the modules defining these things (which in some cases - that you probably won't foresee! - makes it easier for your users to modify things in your module).
To do this use the following syntax:
-- |Convenient import module
module Foo.Import (module All) where
-- Import what you want to export
import Foo.Stuff as All hiding (local_func)
-- You can import several modules into the same namespace for this trick!
-- For example if using your module also requires 'decode' from "Data.Aeson" you can do
import Data.Aeson as All (decode)
You have now conveniently exported these things.
Unfortunately not.
One could imagine a small syntactic addition which would allow the kind of thing you're asking for. Right now it's possible to write:
module M (module M) where
foo = quux
quux = 1+2
You can explicitly export the whole module. But suppose we were to add syntax such that it was possible to hide from that module. Then we would be able to write like this:
module M (module M hiding (quux)) where
foo = quux
quux = 1+2