Getting list of object names in module with template haskell? - haskell

I'd like to be able to take a file with declarations such as:
test_1 = assert $ 1 == 1
test_2 = assert $ 2 == 1
and generate a basic run function like
main = runTests [test_1, test2]
The goal is to get something like Python's nosetest.
Can I do this with template Haskell? I cannot find a lot of documentation on it (there are many broken links in the Wiki).

You might want to look into the test-framework family of packages. In particular, the test-framework-th package provides the Template Haskell function defaultMainGenerator which does exactly what you want for both QuickCheck and HUnit tests, as long as you follow the convention of prefixing HUnit test cases with case_ and QuickCheck properties with prop_.
{-# LANGUAGE TemplateHaskell #-}
import Test.Framework.Providers.HUnit
import Test.Framework.Providers.QuickCheck2
import Test.Framework.TH
import Test.HUnit
import Test.QuickCheck
main = $(defaultMainGenerator)
case_checkThatHUnitWorks =
assert $ 1 == 1
prop_checkThatQuickCheckWorks =
(1 == 1)

There is another way, you don't have to use template haskell. haskell-src-exts can parse Haskell, and you could extract from that.
Or if your purpose is practical, you can make like quickcheck and do a simple-minded parse, i.e. looking for identifiers that start with prop_ in column 0. This is a perfectly adequate solution for real work, though it may be theoretically unsatisfying.

Related

Write surrogate pairs to file using Haskell

This is the code I have:
import qualified System.IO as IO
writeSurrogate :: IO ()
writeSurrogate = do
IO.writeFile "/home/sibi/surrogate.txt" ['\xD800']
Executing the above code gives error:
text-tests: /home/sibi/surrogate.txt: commitBuffer: invalid argument (invalid character)
The reason being is that it is prevented by the GHC itself as they are surrogate code points: https://github.com/ghc/ghc/blob/21f0f56164f50844c2150c62f950983b2376f8b6/libraries/base/GHC/IO/Encoding/Failure.hs#L114
I want to write some test files which needs to have that data. Right now, I'm using Python to achieve what I want - But I would love to know if there is an way (workaround using Haskell) to achieve this.
Sure, just write the bytes you want:
import Data.ByteString as BS
main = BS.writeFile "surrogate.txt" (pack [0xd8, 0x00])

Data.ByteString.Lazy.Internal.ByteString to string?

Trying to write a module which returns the external IP address of my computer.
Using Network.Wreq get function, then applying a lense to obtain responseBody, the type I end up with is Data.ByteString.Lazy.Internal.ByteString. As I want to filter out the trailing "\n" of the result body, I want to use this for a regular expression subsequently.
Problem: That seemingly very specific ByteString type is not accepted by regex library and I found no way to convert it to a String.
Here is my feeble attempt so far (not compiling).
{-# LANGUAGE OverloadedStrings #-}
module ExtIp (getExtIp) where
import Network.Wreq
import Control.Lens
import Data.BytesString.Lazy
import Text.Regex.Posix
getExtIp :: IO String
getExtIp = do
r <- get "http://myexternalip.com/raw"
let body = r ^. responseBody
let addr = body =~ "[^\n]*\n"
return (addr)
So my question is obviously: How to convert that funny special ByteString to a String? Explaining how I can approach such a problem myself is also appreciated. I tried to use unpack and toString but have no idea what to import to get those functions if they exist.
Being a very sporadic haskell user, I also wonder if someone could show me the idiomatic haskell way of defining such a function. The version I show here does not account for possible runtime errors/exceptions, after all.
Short answer: Use unpack from Data.ByteString.Lazy.Char8
Longer answer:
In general when you want to convert a ByteString (of any variety) to a String or Text you have to specify an encoding - e.g. UTF-8 or Latin1, etc.
When retrieving an HTML page the encoding you are suppose to use may appear in the Content-type header or in the response body itself as a <meta ...> tag.
Alternatively you can just guess at what the encoding of the body is.
In your case I presume you are accessing a site like http://whatsmyip.org and you only need to parse out your IP address. So without examining the headers or looking through the HTML, a safe encoding to use would be Latin1.
To convert ByteStrings to Text via an encoding, have a look at the functions in Data.Text.Encoding
For instance, the decodeLatin1 function.
I simply do not understand why you insist on using Strings, when you have already a ByteString at hand that is the faster/more efficient implementation.
Importing regex gives you almost no benefit - for parsing an ip-address I would use attoparsec which works great with ByteStrings.
Here is a version that does not use regex but returns a String - note I did not compile it for I have no haskell setup where I am right now.
{-# LANGUAGE OverloadedStrings #-}
module ExtIp (getExtIp) where
import Network.Wreq
import Control.Lens
import Data.ByteString.Lazy.Char8 as Char8
import Data.Char (isSpace)
getExtIp :: IO String
getExtIp = do
r <- get "http://myexternalip.com/raw"
return $ Char8.unpack $ trim (r ^. responseBody)
where trim = Char8.reverse . (Char8.dropWhile isSpace) . Char8.reverse . (Char8.dropWhile isSpace)

Compile-time check if a name is defined

Is it possible to check if a function is defined, and use it as the Just value of a Maybe type if it is? And use Nothing if it's not defined, of course.
I'm writing a wrapper around atom for use with the TI MSP430 line. Part of what I'm doing is making a function that quickly compiles the code in the right format for MSP430 controllers - for example, compiling an atom to use in a timer interrupt requires a function definition like so:
#pragma vector=TIMERA0_VECTOR __interrupt
void timerAisr(void) {
...
}
At the moment, I have an object that holds references to the function the user would like to use for each different ISR. It looks a bit like this:
mspProgram = MSP430Compilation {
setupFn = Nothing,
setupFnName = "setup",
loopFn = Nothing,
loopFnName = "loop",
timerAISR = Nothing,
timerAISRName = "timerAISR",
And so on. Very configurable - you can choose the name of the function to output in C code, and the Atom to compile for that function. But I've decided I'd like to take more of a convention-over-configuration approach and basically assume some sensible function names. So instead of passing one of these configuration objects, I want the compilation code to check for definitions of sensibly-named functions.
For example, if the user defines an Atom called timerAISR, then my code should compile that atom to a C function named the same, with the appropriate #pragma matter for it to service the timer A interrupt.
So what I need to do is sort of meta-Haskell, checking if the user has defined a function and using that in my library code. I imagine this might involve template Haskell, so I'm off to research it.
EDIT:
I've realised that my original solution was too simplistic once I tried to fit it into my actual code. I hadn't absorbed Haskell's namespacing, so I didn't realise that lookupValueName would not work on values defined in user code. Here's the situation I'm dealing with:
main.hs:
module Main where
import Library
a = 1
main = libraryMain
Library.hs:
{-# LANGUAGE TemplateHaskell #-}
module Library where
import Template
libraryMain :: IO ()
libraryMain = do
$(printSomethingIfIsDefined "a")
$(printSomethingIfIsDefined "b")
Template.hs:
{-# LANGUAGE TemplateHaskell #-}
module Template where
import Language.Haskell.TH
printSomethingIfIsDefined name = do
maybeFn <- lookupValueName name
case maybeFn of
Just fn -> [| putStrLn "It's defined!" |]
Nothing -> [| return () |]
This prints nothing. If I define a in Library.hs, it will print out once, because a is defined in that scope.

Numeric.Probability.Monad not exported from probability package and therefore examples don't work?

I was playing around with the probability package, trying to understand how the various examples work. A number of the examples import Numeric.Probability.Monad which is hidden it seems and therefore means I can't run the examples.
Monty Hall Example:
module Numeric.Probability.Example.MontyHall where
import qualified Numeric.Probability.Distribution as Dist
import qualified Numeric.Probability.Transition as Trans
import Numeric.Probability.Simulation ((~.), )
import Numeric.Probability.Percentage
(Dist, RDist, Trans, )
import qualified Numeric.Probability.Monad as MonadExt
And If i try to run it in ghci
:load "MontyHall.hs"
MontyHall.hs:10:18:
Could not find module `Numeric.Probability.Monad'
it is a hidden module in the package `probability-0.2.4'
Use -v to see a list of the files searched for.
Failed, modules loaded: none.
Clearly I am doing something wrong, as what is the point of examples that can't be run. So what I am doing wrong here?
The only function from Numeric.Probability.Monad used in the MontyHall file is this one:
compose :: Monad m => [a -> m a] -> a -> m a
compose = foldl (flip (<=<)) return
It's a straightforward helper function, and you can just inline it yourself.

Re-export qualified?

suppose you have two modules like
module Foo.A where
foo = 42
and
module Foo.B where
foo = 12
and you want to write a super module
module Foo (
module Foo.A
, module Foo.B
) where
import Foo.A
import Foo.B
which re-exports those modules, you would get a name clash.
Is there a solution for this?
Basically, no. This has been a long-standing feature request by people like the authors of Gtk2hs. Gtk2hs has a very broad module hierarchy where it might make sense to both:
Use the same name in several different modules (e.g. newButton in both Graphics.UI.Gtk.Buttons.Button and Graphics.UI.Gtk.Buttons.CheckButton)
Provide the convenience to the user of importing all these modules with a single import statement
For now, if you want to reexport several modules together all you can do is:
Avoid reusing names in the modules you wish to reexport
Where appropriate, use type classes to allow the same name to be used for several different purposes
Good question. The Haskell Report addresses this:
Exports lists are cumulative: the set of entities exported by an export list is the union of the entities exported by the individual items of the list.
[...]
The unqualified names of the entities exported by a module must all be distinct (within their respective namespace).
According to my limited Haskell knowledge I'd say it's not possible.
You can't export both foos without the name clash unless you use a typeclass (which I shall elaborate on), but there are other options.
You could opt to hide one of the versions of foo:
module Foo
(
module Foo.A,
module Foo.B
)
where
import Foo.A
import Foo.B hiding (foo)
This isn't ideal if you genuinely need both, but if one is rarerly used then it may be simpler to just hide it and expect people to manually reinclude (e.g. by import qualified Foo.B as B (foo), providing B.foo) it if they need it.
You could opt to hide both versions of foo and document that you expect the end user to manually import them if they need them. Under such a scheme, the user could do something like the following:
import Foo.A as A (foo)
import Foo.B as B (foo)
main :: IO ()
main = do
print A.foo
print B.foo
This is actually a fairly common thing to have to do when dealing with multiple container types since many different container types export functions like empty, null and singleton. (To the point where I wish there were actually typeclasses for those, since they are such common operations.)
If you really need both and you're prepared to do a bit of export gymnasics, you can reexport both under different names from within Foo itself:
module Foo (module Foo) where
-- Note that in this case it is important
-- that the module alias matches the
-- name of the exporting module ('Foo')
import Foo.A as Foo hiding (foo)
import Foo.B as Foo hiding (foo)
import qualified Foo.A
import qualified Foo.B
fooA = Foo.A.foo
fooB = Foo.B.foo
Thus any module importing Foo will get Foo.A.foo as fooA (with a value of 42) and Foo.B.foo as fooB (with a value of 12).
If you only have a few clashes to resolve then this is probably the most balanced solution
As another answer has already mentioned, you can use a typeclass, though depending on the context this may be a misuse of the typeclass system.
You could achieve that like so:
module Foo.C where
-- The 'a' dummy argument is necessary to disambiguate
-- which version of 'foo' you intend to use.
class FooProvider a where
foo :: a -> Int
module Foo.B where
import Foo.C
data FooB = FooB
instance FooProvider FooB where
foo _ = 12
module Foo.A where
import Foo.C
data FooA = FooA
instance FooProvider FooA where
foo _ = 42
module Foo (module Exports) where
-- In this case the name of the
-- module alias is unimportant
-- as long as all modules use the same alias.
import Foo.A as Exports
import Foo.B as Exports
import Foo.C as Exports
import Foo
-- 'FooA' and 'FooB' exist solely for
-- the purpose of disambiguating the
-- different versions of 'foo'.
main :: IO ()
main = do
print (foo FooA)
print (foo FooB)
Generally this is less desirable than the aforementioned solutions, particularly for something as simple as a named constant, but sometimes it makes sense to introduce a typeclass. For example, a typeclass such as this:
class Container c where
empty :: c a
singleton :: a -> c a
null :: c a -> Bool
Would work for a number of container types, including [] ('List'), Set, Maybe. Without singleton, it would apply to even more types (e.g. Map, Seq, IntMap). (Note that this could also have included some kind of length function since an empty container would have a length of 0 and a singleton container would have a length of 1. It would however clash with the length in Prelude, which is based on Foldable.)
There may be other possibilities that make use of typeclasses and possibly compiler extensions, but I suspect they'll only increase in complexity from herein.

Resources