I have tried this code in Haskell :
array :: (Ix a) => (a,a) -> [(a,b)] -> Array a b
squares = array (1,100) [(i, i*i) | i <- [1..100]]
But when i run that Code i get this message by GHCi:
The type signature for array lacks an accompanying binding
(The type signature must be given where array is declared)
What exactly is meant with accompanying binding and how to fix that?
Because you define a type signature for array, not squares (array is a library function, you cannot redefine it, you can of course write your own). Now the compiler thinks you aim to define your own array and says: "Got that, but where is your function definition?" it thus lacks a binding (implementation so to speak).
The binding is thus its implementation (here squares = array (1,100) [(i, i*i) | i <- [1..100]]). Furthermore between brackets the compiler also says that you cannot define the function where you want, it must be in the file where the function signature is (the signature is where you define its type so :: (Ix a) => (a,a) -> [(a,b)] -> Array a b).
Given you meant to give a signature to squares, the type signature is too broad. The most generic type signature is:
squares :: (Enum e, Num e, Ix e) => Array e e
squares = array (1,100) [(i, i*i) | i <- [1..100]]
Related
I want to understand how Array.length is implemented. I managed to write it with Array.fold_left:
let length a = Array.fold_left (fun x _ -> x + 1) 0 a
However in the standard library, fold_left uses length so that can't be it. For length there is just this line in the stdlib which I don't understand:
external length : 'a array -> int = "%array_length"
How can I write length without usingfold_left?
EDIT:
I tried to do it with pattern matching, however it is not exhaustive, how can I make the matching more precise? (The aim is to remove the last element and return i+1 when only one element is left)
let length a =
let rec aux arr i =
match arr with
| [|h|] -> i+1
| [|h;t|] -> aux [|h|] (i+1)
in aux a 0;;
The array type is a primitive type, like the int type.
The implementation of many primitives functions on those primitive type is done with either C functions or compiler primitives.
The Array.length function belongs to the compiler primitive category and it is defined in the standard library by:
external length : 'a array -> int = "%array_length"
Here, this declaration bind the value length to the compiler primitive %array_length (compiler primitive names start with a % symbol) with type 'a array -> int. The compiler translates such compiler primitive to a lower level implementation during the translation process from the source code to either native code or bytecode.
In other words, you cannot reimplement Array.length or the array type in general in an efficient way yourself because this type is a basic building block defined by the compiler itself.
For length there is just this line in the stdlib which I don't understand:
The external keyword indicates that this function is implemented in C, and "%array_length" is the C symbol naming this function. The OCaml runtime is implemented in C and some types, like arrays, are built-in (also called primitives).
See for example Implementing primitives in Chapter 20: Interfacing C with OCaml
I tried to do it with pattern matching, however it is not exhaustive, how can I make the matching more precise
Note that OCaml tells you which pattern is not matched:
Here is an example of a case that is not matched:
[| |]
So you have to account for empty vectors as well.
I've created a:
newType Board = Board (Array (Int, Int) Life)
, where
data Life = Alive|Dead
Im trying to make a function to save the board to a String by pattern matching:
showBoard:: Config -> String
showBoard Board(array ((0, 0), (w, h)) [(a:as)]) = *code*
But this only gives me "Parse error in pattern: array". I cant see what's wrong?
You can only pattern-match on data constructors. array is not a data constructor; it is a regular function that internal uses the Array data constructor(s) to create and return an Array value. The internal details
of an Array are not exposed, preventing you from pattern-matching on them.
Instead, you need use the functions provided for looking at an Array value. These can be composed with a function that does take arguments you can pattern match on.
-- bounds :: Array i e -> (i, i)
-- elems :: Array i e -> [e]
showConfig :: Board -> String
showConfig (Board arr) = showConfig' (bounds arr) (elems arr)
where showConfig' :: ((Int,Int),(Int,Int)) -> [Life] -> String
showConfig' ((0,0),(w,h)) (a:as) = ...
If you modify your Board type to
newtype Board = Board { getArray :: Array (Int, Int) Life }
you can rewrite showConfig in an applicative style:
showConfig = (showConfig' <$> boards <*> elems) . getArray
where showConfig' ((0,0),(w,h)) (a:as) = ...
In Julia, I want to specify the type of a function argument as an array of arrays. So I have
function foo{T <: Any}(x::Array{Array{T}})
but if I set the argument x in the REPL, for example:
x = Array[[0,1],[1,2,3],[0,1,2,4]]
then it automatically gets the following type assignment (for example), which includes its dimensions:
x::Array{Array{T,N},1}
so that I get the error
ERROR: `foo` has no method matching foo(::Array{Array{T,N},1}).
I don't want to restrict the array dimensions at all, so was thinking that the solution maybe something along the lines of
function foo{T <: Any, N <: Number}(x::Array{Array{T,N},N})
but this doesn't work either.
How can I specify the argument type to be an array of arrays?
Given an array of arrays x = Array[isodd(i) ? [1i,2i] : [1.0i 2.0i] for i=1:10], Julia reports its type as Array{Array{T,N},1}. This is deceiving, as it seems to imply that there exists some T and some N for which the above type will match. But that's not the case: the odd elements will be of type Array{Int,1}, and the evens are Array{Float64,2}. So when you try to write a method for foo with the type parameters:
foo{T,N}(::Array{Array{T,N},1}) = T,N
What are T and N for x? Clearly, there is no such N — it's both 1 and 2! And the elements of these subarrays aren't of type Any — they're both Int and Float64. The same applies for Array[[0,1],[0,1,2]], even though in your example you know that T and N are consistent, Julia's type system doesn't… and you could potentially push elements that aren't Int vectors.
There are quite a few ways around this. The best approach is to try to make sure that your arrays always have concrete (or at least uniform) element types, but that's not always possible. Given your example x above, you could instead write: x = Array{Int,1}[[0,1],[1,2,3],[0,1,2,4]].
Another alternative is to change your function signature:
foo{N}(x::Array{Array,N}) = 1 # Will *only* work for arrays like x above
foo{T<:Array, N}(x::Array{T,N} = 2 # Will work for all arrays of arrays
The first will only apply if you have exactly that type due to invariance, whereas the second will work for all Arrays of Arrays, both poorly-typed and concrete.
(Edit: As a final note, N<:Number won't match literal numbers. It will match types that are a subtype of Number, like Real or Int. There's currently no way to express that a type parameter must be a value of type Int beyond the convention that N is an integer).
As I've been learning haskell I've enjoyed the pure parts but now I am stumbling through the monadic and IO parts and probably experiencing what some people find truly infuriating about the language. I solving a project euler problem and I simple want a mutable array because I have to update elements frequently by index. I tried Vectors but couldn't get them working so I tried Data.Array.IO. I can read and write elements fine but I can't display the array in terminal the way I want. So far I have this.
test = do
arr <- newArray (1,10) 37 :: IO (IOArray Int Int)
a <- readArray arr 1
writeArray arr 1 64
b <- readArray arr 1
dispArray arr
return ()
dispArray arr = do
(a,b) <- getBounds arr
printf "["
dispArray' arr a
printf "]\n"
where dispArray' arr i = do
(a,b) <- getBounds arr
if i < a || i > b
then return ()
else do
v <- readArray arr i
print v
dispArray' arr (i+1)
The ouput of this as you would expect is this:
[64
37
37
37
37
37
37
37
37
37
]
But this is inconvenient and I want this [64,37,37,37.... like this. I've seen functions that are something like toList, but I don't want this. I don't want to convert to a list everytime I display. So I figured I would need to use printf. So I replaced print v with printf " %s," (show v). But this doesn't compile. I don't know why. I thought it would because print :: Show a => a -> IO () and show :: Show a => a -> String so why wouldn't it work because %s signifies a string? So I then put to calls next to each other. To see if printf would even work.
printf " %s," "hello"
print v
Which compiles and displays:
[ hello,64
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
hello,37
]
Why can I not use show v? Why is haskell IO so infuriating to beginners?
This is an interesting type-checking puzzle.
The error message that the call to printf produces is
Could not deduce (PrintfType (m a0))
arising from the ambiguity check for `dispArray'
The phrases Could not deduce and ambiguity typically hint at the fact that GHC has
insufficient type information in order to conclude how this program should be typed. This might be a real type error, but it's also possible that it can be fixed simply by providing more type information (and this is the case here).
The culprit here is really printf, combined with the flexibility of the mutable array interface, and not so much Haskell's IO system. The type of printf is an ingenious hack, but still a hack. In order to know a flexible number of parameters of various types that depend on just the format string, printf has a type that isn't very safe nor very informative:
printf :: PrintfType r => String -> r
So all we really know for sure is that the first argument is of type String. The rest can be any type r that is in the type class PrintfType.
The details of the instances do not matter. What's interesting is that show produces a String, and if we apply printf to a format string and then a show-produced second string, we are still left with a rather uninformative type:
> :t printf "%s," (show 2)
printf "%s," (show 2) :: PrintfType t => t
In particular, there's no indication here that the result is to be in the IO monad.
This normally wouldn't be a problem, if GHC could conclude from the context that you're in IO. But within dispArray', the only other functions you are calling are readArray, getBounds, return (and dispArray' recursively). None of these functions specifies that it lives in IO either. In particular, all of the array functions are overloaded over the monad, for example:
getBounds :: (Ix i, MArray a e m) => a i e -> m (i, i)
(And indeed, getBounds could, for example, also work in an ST monad context.) So there's simply nothing in dispArray' that determines that you live in IO. And that in turn means that GHC cannot resolve the type of printf.
As I said, it's a consequence of the desired flexibility of printf that printf itself cannot provide this information, and it has to be available externally.
The solution is easy enough. As suggested in one of the comments, it is sufficient to annotate the result type of the call to printf:
printf "%s," (show v) :: IO ()
As you're using printf anyway (and if you're actually only interested in arrays of decimal numbers), you could also use:
printf "%d," v :: IO ()
It would also sufficient (but less clear to the reader) to give a type signature for anything else within the definition of dispArray' so that it fixes the return type to be IO (). For example, you could annotate the return () in the then-branch of the if expression:
return () :: IO ()
The incantation you want is:
putStr (show v)
That prints out v without a newline.
I see that I can map a function over mutable arrays with mapArray, but there doesn't seem to be something like mapM (and mapM_). mapArray won't let me print its elements, for example:
import Data.Array.Storable
arr <- newArray (1,10) 42 :: IO -- answer to Life, Universe and Everything
x <- readLn :: IO Int
mapArray (putStrLn.show) arr -- <== this doesn't work!
The result will be:
No instances for (MArray StorableArray Int m,
MArray StorableArray (IO ()) m)
arising from a use of `mapArray' at <interactive>:1:0-27
Possible fix:
add an instance declaration for
(MArray StorableArray Int m, MArray StorableArray (IO ()) m)
In the expression: mapArray (putStrLn . show) arr
In the definition of `it': it = mapArray (putStrLn . show) arr
Is there something like that in Haskell (or in GHC even if not standard Haskell)?
Also, I found no foldr/foldl functions for arrays (mutable or not). Do they exist?
Thanks a lot!
Import the module Data.Traversable. It defines a typeclass for just what you want with instances already defined for array and all sorts of things. It has generalized versions of sequence and mapM, plus some even more general functions that you probably won't bother with very often.
Just a simple
import Data.Traversable as T
T.mapM doIOStuff arr
works fine.
Perhaps use one of the other array libraries, if you're doing a lot of mutation? Like uvector?
Otherwise,
forM_ [1..n] \$ \i ->. unsafeWrite x i
should be fine.
For the example of printing all the elements: you can use "mapM_ print . elems".
But it sounds like you want to create a new array where each value is the result of a monadic action of the previous one? In that case:
arrayMapM :: (Monad m, Ix i) => (a -> m b) -> Array i a -> m (Array i b)
arrayMapM func src =
liftM (listArray (bounds src)) . mapM func . elems $ src