I am trying to get started with the LLVM binding for Haskell. A great place to start is Hello World.
The following is from a blog by the author of the binding.
bldGreet :: CodeGenModule (Function (IO ()))
bldGreet = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
greetz <- createStringNul "Hello, World!"
func <- createFunction ExternalLinkage $ do
tmp <- getElementPtr greetz (0::Word32, (0::Word32, ()))
call puts tmp -- Throw away return value.
ret ()
return func
It does not compile.
Instead I get "Ambiguous type variable n0' in the constraint:
(type-level-0.2.4:Data.TypeLevel.Num.Sets.NatI n0)
arising from a use ofgetElementPtr0'
Probable fix: add a type signature that fixes these type variable(s)"
Here is a variation that does work
llvmModule :: TFunction (IO Word32)
llvmModule =
withStringNul "Hello world!" $ \s -> do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
main <- newNamedFunction ExternalLinkage "main" :: TFunction (IO Word32)
defineFunction main $ do
tmp <- getElementPtr0 s (0::Word32, ())
_ <- call puts tmp
ret (0::Word32)
return main
The first seems more natural. The question I have is what is the ambiguity in the first, and how do I fix it. The second question I have is why is the second not ambiguous.
Okay. So I solved the problem. It is indeed a typeclass thing. And it has only confused me more. However, I do have an answer to the solution. But do feel free to help my understanding out. First, some digging. The function createStringNul has type
createString :: String -> TGlobal (Array n Word8)
Fine. The problem the compiler was having is that the "n" in the Array type is ambiguous. It could literally be anything in the world. Lookup, Array, and you see
newtype Array n a
Now it is not so obvious, but upon a little digging, in particular wrt the call to getElementPtr, one finds that the n, really should be a Nat n, which is a type-level way to fix the size of the array. Now, the definition of Array n a, does not actually care it is really just a type synonym for [a]. So you can use D0, or D9 or whatever you want from the
Data.TypeLevel.Num.Reps
package. Fixing the size of the array, while a good idea was not actually taken into consideration by this function. But anyways, changing
greetz <- createStringNul "Hello, World!"
to
greetz <- createStringNul "Hello, World!" :: TGlobal (Array D0 Word8)
works.
Here is the interesting part... I did not expect it to work. D0 is supposed to be 0, so I did not understand why it was allowing me to store so many characters in a 0 size "Array" However, if you look at the source code, it is immediately clear that the type restriction is not actually payed attention to.
Fine, whatever, upon compiling one realizes that the createStringNul is deprecated, and withStringNul is preferred instead. Except I don't completely understand how withStringNul's types work.
createStringNul is marked as deprecated in the current version of llvm (3.0.1.0). Use withStringNul:
import Data.Word
import LLVM.Core
bldGreet :: CodeGenModule (Function (IO ()))
bldGreet = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
func <- withStringNul "Hello, World!" $ \greetz ->
createFunction ExternalLinkage $ do
tmp <- getElementPtr greetz (0::Word32, (0::Word32, ()))
_ <- call puts tmp -- Throw away return value.
ret ()
return func
As to what causes the error in the first example, it's related to the fact that withStringNul has a more informative type: withStringNul :: String -> (forall n . Nat n => Global (Array n Word8) -> a) -> a -- cf. to createStringNul :: String -> TGlobal (Array n Word8). The function argument of withStringNul has a higher-rank type - it means that the function works for all n where n is a natural number.
If you really want to use createStringNul, you can make the first example compile by adding an explicit type signature for greetz:
{-# LANGUAGE TypeOperators #-}
module Test
where
import Data.Word
import Data.TypeLevel.Num.Reps
import LLVM.Core
bldGreet :: CodeGenModule (Function (IO ()))
bldGreet = do
puts <- newNamedFunction ExternalLinkage "puts" :: TFunction (Ptr Word8 -> IO Word32)
greetz <- createStringNul "Hello, World!"
func <- createFunction ExternalLinkage $ do
tmp <- getElementPtr (greetz :: Global (Array (D1 :* D3) Word8)) (0::Word32, (0::Word32, ()))
call puts tmp -- Throw away return value.
ret ()
return func
The :* type constructor comes from the type-level package and is used to construct type-level numbers. D1 :* D3 means that the array has size 13.
Related
Sorry if I am being silly but I am a beginner in Haskell ans I am trying to make a print a List with putStrLn but i am not sure how to solve the next problem:
And I am trying to made a basic print List in Haskell with the code:
import System.IO
array = map show [1, 2, 3, 4]
main :: IO ()
main = do
map putStrLn array
but the compiler give me:
8 main.hs:7:3: error:
7 • Couldn't match expected type ‘IO ()’ with actual type ‘[IO ()]’
6 • In a stmt of a 'do' block: map putStrLn array
5 In the expression: do map putStrLn array
4 In an equation for ‘main’: main = do map putStrLn array
How I should fix it?
Haskell handles IO quite differently than other languages.
In a language like Java, System.Out.println(3) is a statement which does not evaluate to a value, so you can't even write something like x = System.Out.println(3);.
In a language like Lisp, (print 3) evaluates to 3 and, in the process of evaluation, prints 3. So saying something like (setq x (print 3)) will set the value of x to 3 and also print 3.
In Haskell, putStrLn "3" represents the command to print 3. Thus, saying x = putStrLn "3" does absolutely nothing except assign x to the command putStrLn "3".
Let's look at some types. We have
map :: (a -> b) -> [a] -> [b]
putStrLn :: String -> IO ()
Thus, we should have
map putStrLn :: [String] -> [IO ()]
map putStrLn array :: [IO ()]
In other words, map putStrLn array is a list of "IO actions" which result in a value of type () (basically, this means that executing the actions results in no extra information).
However, in order to write
main :: IO ()
main = map putStrLn array
which is what
main :: IO ()
main = do map putStrLn array
translates to, we need map putStrLn to be of type IO (), NOT of type [IO ()].
If you wish to execute an action for each element of a list, you can use the for_ function, which has type for_ :: (Foldable g, Applicative f) => g a -> (a -> f ()) -> f (). IO is Applicative and [] is Foldable, so in particular for_ :: [String] -> (String -> IO ()) -> IO () is one type that for_ can take. The code looks like
import Data.Foldable (for_)
array :: [String]
array = map show [1, 2, 3, 4]
main :: IO ()
main = for_ array putStrLn
This would be equivalent in an imperative language to
for each x in array do {
putStrLn x;
}
I have a function "management" that checks parameters and return a Maybe (String):
If there are not parameter -> return Nothing
If my parameter is equal to "-h" -> Return a string help
My problem arrived when I get a file and check if this file exists.
Couldn't match expected type ‘Maybe String’
with actual type ‘IO (Either e0 a2)’
managagment :: [String] -> Maybe (String)
managagment [] = Nothing
managagment ["-h"] = Just (help)
managagment [file] = try $ readFile file >>= \result -> case result of
Left e -> Nothing
Right content -> Just (content)
There are several problems
Function application ($) is lower precedence than bind (>>=)
You said:
try $ readFile file >>= \res...
Which means
try ( readFile file >>= \res... )
But you wanted:
try ( readFile file ) >>= \res...
IO (Maybe a) and Maybe a are distinct
You have a function using IO (via readFile and try) but many of the cases do not return an IO result (Nothing and Just content).
Solution: Return via return Nothing or pure Nothing to lift a value into the IO monad.
The exception type was ambiguous
The try function can catch any exception type, just look at the signature:
try :: Exception e => IO a -> IO (Either e a)
When you totally ignore the exception you leave the type checker with no information to decide what e should be. In these situations an explicit type signature is useful, such as:
Left (e::SomeException) -> pure Nothing
managagment is partial
managagment ["a","b"] is undefined as is any input list of length over one. Consider a final equational definition of:
managagment _ = managagment ["-h"]
Or more directly:
managagment _ = pure $ Just help
Style and other notes
managagment should probably management
Just (foo) is generally Just foo
help is not a function that returns a String. It is a value of type String.
The example was not complete, missing imports and help.
Fixed Code
Consider instead:
#!/usr/bin/env cabal
{- cabal:
build-depends: base
-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE LambdaCase #-}
import Control.Exception (try, SomeException)
main :: IO ()
main = print =<< management []
help :: String
help = "so helpful"
management :: [String] -> IO (Maybe String)
management [] = pure Nothing
management ["-h"] = pure $ Just help
management [file] =
try (readFile file) >>=
\case
Left (e::SomeException) -> pure Nothing
Right content -> pure $ Just content
management _ = pure $ Just help
And test as such:
% chmod +x x.hs
% ./x.hs
I am making a maze generator and wish to visualize the maze by printing. I have a wall type and a function that generates a random maze of those walls.
import qualified Data.Graph.Inductive as Graph
import Data.Graph.Inductive (Gr, prettyPrint)
data WeightedWall = WeightedWall (Int, Int, Int) Orientation deriving (Eq)
weightedGrid :: MonadRandom m => Int -> Int -> Gr () (m WeightedWall)
However, when I call prettyPrint(weightedGrid 10 10), I get this error:
Ambiguous type variable ‘m0’ arising from a use of ‘prettyPrint’
prevents the constraint ‘(Show
(m0 WeightedWall))’ from being solved.
Probable fix: use a type annotation to specify what ‘m0’ should be.
What am I missing in my code to fix this?
You will want your pretty printer to have type:
prettyPrint :: WeightedWall -> String
Then, you will need to pluck a WeightedWall from your MonadRandom instance, pass it to prettyPrint, and then print the String in the IO monad.
The getRandomR function is a member of the MonadRandom typeclass, so it doesn't tell us which MonadRandom instance you are using. I'm going to assume IO since it kills two birds with one stone (the random source and the printing). Your main function could look as follows:
main :: IO ()
main = do
ww <- weightedGrid 10 10 -- pluck weighted wall from MonadRandom instance IO
putStrLn $ prettyPrint ww
I ended up doing:
pp :: WeightedWall -> String
pp (WeightedWall (a, b, c) _) = show a ++ " " ++ show b ++ " " ++ show c
main :: IO ()
main = do
ww <- mapM Data.Graph.Inductive.edgeLabel $ labEdges (weightedGrid 10 10)
forM_ (map pp ww) putStrLn
I have a file number.txt which contains a large number and I read it into an IO String like this:
readNumber = readFile "number.txt" >>= return
In another function I want to create a list of Ints, one Int for each digit…
Lets assume the content of number.txt is:
1234567890
Then I want my function to return [1,2,3,4,5,6,7,8,9,0].
I tried severall versions with map, mapM(_), liftM, and, and, and, but I got several error messages everytime, which I was able to reduce to
Couldn't match expected type `[m0 Char]'
with actual type `IO String'
The last version I have on disk is the following:
module Main where
import Control.Monad
import Data.Char (digitToInt)
main = intify >>= putStrLn . show
readNumber = readFile "number.txt" >>= return
intify = mapM (liftM digitToInt) readNumber
So, as far as I understand the error, I need some function that takes IO [a] and returns [IO a], but I was not able to find such thing with hoogle… Only the other way round seemes to exist
In addition to the other great answers here, it's nice to talk about how to read [IO Char] versus IO [Char]. In particular, you'd call [IO Char] "an (immediate) list of (deferred) IO actions which produce Chars" and IO [Char] "a (deferred) IO action producing a list of Chars".
The important part is the location of "deferred" above---the major difference between a type IO a and a type a is that the former is best thought of as a set of instructions to be executed at runtime which eventually produce an a... while the latter is just that very a.
This phase distinction is key to understanding how IO values work. It's also worth noting that it can be very fluid within a program---functions like fmap or (>>=) allow us to peek behind the phase distinction. As an example, consider the following function
foo :: IO Int -- <-- our final result is an `IO` action
foo = fmap f getChar where -- <-- up here getChar is an `IO Char`, not a real one
f :: Char -> Int
f = Data.Char.ord -- <-- inside here we have a "real" `Char`
Here we build a deferred action (foo) by modifying a deferred action (getChar) by using a function which views a world that only comes into existence after our deferred IO action has run.
So let's tie this knot and get back to the question at hand. Why can't you turn an IO [Char] into an [IO Char] (in any meaningful way)? Well, if you're looking at a piece of code which has access to IO [Char] then the first thing you're going to want to do is sneak inside of that IO action
floob = do chars <- (getChars :: IO [Char])
...
where in the part left as ... we have access to chars :: [Char] because we've "stepped into" the IO action getChars. This means that by this point we've must have already run whatever runtime actions are required to generate that list of characters. We've let the cat out of the monad and we can't get it back in (in any meaningful way) since we can't go back and "unread" each individual character.
(Note: I keep saying "in any meaningful way" because we absolutely can put cats back into monads using return, but this won't let us go back in time and have never let them out in the first place. That ship has sailed.)
So how do we get a type [IO Char]? Well, we have to know (without running any IO) what kind of IO operations we'd like to do. For instance, we could write the following
replicate 10 getChar :: [IO Char]
and immediately do something like
take 5 (replicate 10 getChar)
without ever running an IO action---our list structure is immediately available and not deferred until the runtime has a chance to get to it. But note that we must know exactly the structure of the IO actions we'd like to perform in order to create a type [IO Char]. That said, we could use yet another level of IO to peek at the real world in order to determine the parameters of our action
do len <- (figureOutLengthOfReadWithoutActuallyReading :: IO Int)
return $ replicate len getChar
and this fragment has type IO [IO Char]. To run it we have to step through IO twice, we have to let the runtime perform two IO actions, first to determine the length and then second to actually act on our list of IO Char actions.
sequence :: [IO a] -> IO [a]
The above function, sequence, is a common way to execute some structure containing a, well, sequence of IO actions. We can use that to do our two-phase read
twoPhase :: IO [Char]
twoPhase = do len <- (figureOutLengthOfReadWithoutActuallyReading :: IO Int)
putStrLn ("About to read " ++ show len ++ " characters")
sequence (replicate len getChar)
>>> twoPhase
Determining length of read
About to read 22 characters
let me write 22 charac"let me write 22 charac"
You got some things mixed up:
readNumber = readFile "number.txt" >>= return
the return is unecessary, just leave it out.
Here is a working version:
module Main where
import Data.Char (digitToInt)
main :: IO ()
main = intify >>= print
readNumber :: IO String
readNumber = readFile "number.txt"
intify :: IO [Int]
intify = fmap (map digitToInt) readNumber
Such a function can't exists, because you would be able to evaluate the length of the list without ever invoking any IO.
What is possible is this:
imbue' :: IO [a] -> IO [IO a]
imbue' = fmap $ map return
Which of course generalises to
imbue :: (Functor f, Monad m) => m (f a) -> m (f (m a))
imbue = liftM $ fmap return
You can then do, say,
quun :: IO [Char]
bar :: [IO Char] -> IO Y
main = do
actsList <- imbue quun
y <- bar actsLists
...
Only, the whole thing about using [IO Char] is pointless: it's completely equivalent to the much more straightforward way of working only with lists of "pure values", only using the IO monad "outside"; how to do that is shown in Markus's answer.
Do you really need many different helper functions? Because you may write just
main = do
file <- readFile "number.txt"
let digits = map digitToInt file
print digits
or, if you really need to separate them, try to minimize the amount of IO signatures:
readNumber = readFile "number.txt" --Will be IO String
intify = map digitToInt --Will be String -> [Int], not IO
main = readNumber >>= print . intify
I have a small Haskell function that is supposed to accept an STUArray, modify some of the elements, and then return the changed array. It will be called from another function working in the ST s (STUArray s Int Word32) monad. It part of a fast PBKDF2 function that I am trying to write. This function does SHA-1 padding for a fixed sized message (160-bits).
Here is my code:
padFixed :: STUArray s Int Word32 -> ST s (STUArray s Int Word32)
padFixed block = do
unsafeWrite block 5 0x80000000
unsafeWrite block 15 160
return block
The array will contain the 20 bytes from a previous SHA-1 run, plus 44 bytes of zeros. It will add the required padding as per RFC 3174.
How can I rewrite it so is "takes" the array out of the monad, works on it, and then puts it back? The signature should be padFixed :: ST s (STUArray s Int Word32), without the block parameter.
Is this possible? I could not find any functions in the library that let me extract the array from the monad, but maybe I missed something.
Are there any good tutorials on the STArray?
No, it's not possible; ST doesn't have those semantics. The monad is ST s, and not ST s (STUArray s a). ST s is just a monad for keeping track of mutable state; which structures you choose to allocate and use inside a single ST region are up to you. If you have a bunch of computations which all operate on the same STUArray, you can use ReaderT:
type Hasher s = ReaderT (STUArray s Int Word32) (ST s)
padFixed :: Hasher ()
padFixed = do
block <- ask
unsafeWrite block 5 0x80000000
unsafeWrite block 15 160
The Reader r monad is just a wrapper around r ->; a value of type Reader r a is just a function r -> a. This is essentially a way to compute a while having access to a value of type r. The ReaderT r monad transformer just allows you to provide access to a variable of type r to an arbitrary monadic computation; thus, ReaderT (STUArray s Int Word32) (ST s) is an ST s computation which has access to some array. Note that you don't need to return the array from padFixed; the monad bind will handle all of that.
This'll be a little bit of a pain to write, since we'll have to keep asking for the array. Luckily, we can write some combinators to handle this for us:
{-# LANGUAGE RankNTypes, GeneralizedNewtypeDeriving #-}
import Data.Word
import Control.Applicative
import Control.Monad.Reader
import Control.Monad.ST
import Data.Array.ST (STUArray, runSTUArray)
import qualified Data.Array.Base as A
import Data.Array.Unboxed (UArray)
newtype Hasher s a =
Hasher { getHasher :: ReaderT (STUArray s Int Word32) (ST s) a }
deriving (Functor, Applicative, Monad, MonadReader (A.STUArray s Int Word32))
hasherToST :: Hasher s () -> (Int,Int) -> ST s (STUArray s Int Word32)
hasherToST (Hasher r) bounds = do
block <- A.newArray bounds 0
runReaderT r block
return block
runHasher :: (forall s. Hasher s ()) -> (Int,Int) -> UArray Int Word32
runHasher h bounds = runSTUArray $ hasherToST h bounds
-- Perhaps private to this module, perhaps not
liftST :: ST s a -> Hasher s a
liftST = Hasher . lift
----- We can lift the functions which act on an STUArray -----
getBounds :: Hasher s (Int,Int)
getBounds = liftST . A.getBounds =<< ask
-- I'd recommend against removing the `unsafe` from the name; this function
-- could segfault, after all.
unsafeReadBlock :: Int -> Hasher s Word32
unsafeReadBlock i = do
block <- ask
liftST $ A.unsafeRead block i
unsafeWriteBlock :: Int -> Word32 -> Hasher s ()
unsafeWriteBlock i x = do
block <- ask
liftST $ A.unsafeWrite block i x
----- And then, perhaps in a separate module: -----
padFixed :: Hasher s ()
padFixed = do
unsafeWriteBlock 5 0x80000000
unsafeWriteBlock 15 160
(Note that I couldn't inline hasherToST inside of runHasher, probably because of the higher-rank types blocking inference.)
Basically, we wrap the ReaderT (STUArray s Int Word32) (ST s) into a newtype instead of a type synonym, and lift some basic array primitives up to work on the always-available block. You don't even need to derive MonadReader for the Hasher type if you don't want, as long as you lift all the necessary functions. But once you've done this, your hashing code can talk about the array implicitly.
No, you're confused; that's not possible. Think of STUArray s i e as being a pointer to the beginning of a block of memory. You have to pass that pointer around to anything that needs to modify that block of memory; you can't just conjure it up out of thin air.
But you don't need to return it. Presumably the caller already has the pointer.
You can use the freeze and thaw functions to convert to and from a UArray.
However either this will incur a performance penalty, or you need to use the "unsafe" variants. Since you're already doing unsafe writing, that's probably OK.