Returning a dependent pair from a foreign function - ffi

I have the following Chez support file:
(define list-copy-with-length (xs)
(cons (length xs) (list-copy xs)))
and I have this Idris file:
%foreign "scheme,chez:list-copy-with-length"
prim__listToVect : List t -> (Nat, Vect n t)
listToVect : List t -> (n ** Vect n t)
listToVect ls =
let (n, vs) = prim__listToVect ls
in MkDPair n vs
Naturally, type-checking fails on this code, because the compiler does not know that the n defined in the let expression is the same as the n in the return type of listToVect.
I tried a few guesses at using believe_me to fix this, but I wasn't able to figure it out. Is it possible to define a function like this? What is the correct way to do it, without incurring significant runtime cost of recursively re-computing the length (as in Data.Vect.filter)?
Here is one such guess:
listToVect : {t : _} -> {n : _} -> List t -> (n ** Vect n t)
listToVect ls =
let (n', vs) = prim__listToVect ls
itsEqualDamnit : Equal n' n = believe_me ()
in rewrite itsEqualDamnit in MkDPair n vs
Ideally I'd like to entirely avoid unpacking the pair anyway, because (at least in the Chez backend), pairs and depdendent pairs are both represented identically as cons cells.

believe_me is already an unsafe cast. Just... cast the Vect?
%foreign "scheme,chez:list-copy-with-length"
prim__listToVect : List t -> (Nat, Vect n t)
listToVect : List t -> (n ** Vect n t)
listToVect ls =
let (n, vs) = prim__listToVect {n = 0} ls
in MkDPair n (believe_me vs)
Your Scheme code is wrong: define's syntax is not like that and list-copy-to-vect needs three arguments, since prim__listToVect has three arguments (t, n, and a List t). Note that I pass a dummy in for n on the Idris side.
(define (list-copy-with-length t n xs) (cons (length xs) (list-copy xs)))
You can be even more direct by pairing this Scheme definition
(define (idris-prim-listToVect t xs) (cons (length xs) (list-copy xs)))
With this Idris
%foreign "scheme,chez:idris-prim-listToVect"
prim__listToVect : List t -> (Nat, List t)
listToVect : List t -> (n ** Vect n t)
listToVect xs = believe_me (prim__listToVect xs)
(This works since, as you noted, a DPair is represented the same as a normal pair and List is represented the same as a Vect.)

Related

How to change for loop with an array module function?

This is a school assignment. I'm trying to make a function which takes an array A and makes a new array B, which is telling how many repeated numbers there are in an array. For example A is this:
A = [|2;9;9;2;2;4|]
The B would be:
B = [|3;2;2;3;3;1|]
Ny code is right now like this and working perfectly:
let A = [|2;9;9;2;2;4|]
let n = A.Length - 1
let B = Array.create A.Length 0
for i = 0 to n do
Array.iter (fun j -> if i <> j && A.[i]=j then B.[i] <- (B.[i] + 1)) A
printfn "%A" B
My question is, how much would asymptotic time be? I know the first for loop is O(n), but what about Array.iter? And is there any way to switch the first for loop with an array function?
Array.iter is linear in the array length, so your for loop is essentially O(n²) in time complexity. Replacing the loop with another Array.iter is possible but would not change the time complexity.
If you can solve the problem whichever way you want, I suggest using a Map to aggregate the numbers and their frequencies, then mapping the original array into one showing these frequencies. Since this is a school assignment, you should probably wait until after your submission deadline before you look at the following code:
let numFrequency (a : _ []) =
let m =
(Map.empty, a)
||> Array.fold (fun m n ->
Map.tryFind n m
|> Option.defaultValue 0
|> fun x -> Map.add n (x + 1) m)
Array.map (fun n -> Map.find n m) a
let A = [|2; 9; 9; 2; 2; 4|]
let B = numFrequency A
printf "%A\n%A\n" A B

Remembering old data

Remembering your first time (in a Haskell loop)
I am trying to teach myself a little Haskell by going through some Hackerrank questions.
The question I am looking at involves reading in sets of co-ordinates (x1,y1) and (x2,y2) and
Determining the perimeter of the polygon drawn by those co-ordinates.
Here is my code so far:
-- Calculate length of line given points x1,y2, x2,y2
calc_length:: Int -> Int -> Int -> Int -> Float
calc_length x1 y1 x2 y2 =
sqrt ( fromIntegral (height ^2 + width ^2) )
where height = abs( y2 - y1)
width = abs( x2 - x1)
main = do
x <- readLn :: IO Double
forM_ [1,2..(x / 2)] $ \lc -> do
line1 <- getLine
let wds1 = map (\str -> read str::Int) (words $ line1)
line2 <- getLine
let wds2 = map (\str -> read str::Int) (words $ line2)
print ( wds1, wds2)
The problem I have is that I need to calculate the distance between the first and last co-ordinates I.e. REMEMBER the first pair of numbers entered ( stored in line1). But after multiply iterations the first pair will be lost. I have tried using global variables to store the first calling of getLine (with little success, and even if that had worked I don’t it think it would help.)
I get the feeling that there is a more functional approach I could try but just don’t know how.
I am not looking for a full coded solution just an approach that points me in a better direction.
Any thoughts?
You asked for a more functional way of thinking about this, so I'm going to try to provide that. You said you're new to Haskell, so I apologize in advance if this touches on things you haven't explored yet. Feel free to ask for clarification in any part of it.
First off, let's segment your calcLength function a bit more. We're passing it two points, so rather than passing four arguments, let's pass only two.
data Point a = Point a a
calcLength :: Floating a => Point a -> Point a -> a
calcLength (Point x1 y1) (Point x2 y2) = sqrt (height ^ 2 + width ^ 2)
where height = abs (y2 - y1)
width = abs (x2 - x1)
Now let's write a function that reads a single point. We'll call this from main rather than reading two numerical values separately in main.
readPoint :: (Floating a, Read a) => IO (Point a)
readPoint = Point <$> readLn <*> readLn
I'm using applicative syntax here. If you're more familiar with do-notation, the equivalent would be
readPoint :: (Floating a, Read a) => IO (Point a)
readPoint = do
x <- readLn
y <- readLn
return $ Point x y
Now for the meat of your question. We want to take a list of things (points in your case) and produce adjacent pairs, making sure to loop around to the beginning. Let's stop thinking about it in terms of points for a moment and just write a function that works on any list of things.
-- We're going to take a list of things and produce a list of pairs of those things
loopedPairs :: [a] -> [(a, a)]
-- If the original list is empty, return the empty list
loopedPairs [] = []
-- Otherwise, start recursing
loopedPairs (x:xs) = go x xs
-- Here, we're pairing off all the elements
where go x' (y:ys) = (x', y) : go y ys
-- Because we defined this as an inner function, we can still access
-- the original first element, effectively "remembering" it like you
-- were asking about. Note that we never use any "global" storage or
-- mutable state to do this, just a bit of variable scope.
go x' [] = [(x', x)]
Now we'll write a perimeter function. It's good to separate as much of your "pure" non-IO logic from the IO work as possible, so we want to factor this out of main.
newtype Polygon a = Polygon [Point a]
perimeter :: Floating a => Polygon a -> a
perimeter (Polygon xs) = sum . map (\(a, b) -> calcLength a b) $ loopedPairs xs
We take a polygon, which is really just a list of points, pair off all of our points using loopedPairs, then calculate the length between each of them and sum the results.
With that in mind, main is fairly short.
main :: IO ()
main = do
n <- readLn :: IO Int
points <- replicateM n (readPoint :: IO (Point Double))
let result = perimeter (Polygon points)
print result
We read in the number of points, then we read each point (replicateM essentially means "do this thing n times and accumulate the result into a list). Then we calculate the perimeter and print it out.
Runnable solution:
import Control.Monad
data Point a = Point a a
newtype Polygon a = Polygon [Point a]
calcLength :: Floating a => Point a -> Point a -> a
calcLength (Point x1 y1) (Point x2 y2) = sqrt (height ^ 2 + width ^ 2)
where height = abs (y2 - y1)
width = abs (x2 - x1)
readPoint :: (Floating a, Read a) => IO (Point a)
readPoint = Point <$> readLn <*> readLn
loopedPairs :: [a] -> [(a, a)]
loopedPairs [] = []
loopedPairs (x:xs) = go x xs
where go x' (y:ys) = (x', y) : go y ys
go x' [] = [(x', x)]
perimeter :: Floating a => Polygon a -> a
perimeter (Polygon xs) = sum . map (\(a, b) -> calcLength a b) $ loopedPairs xs
main :: IO ()
main = do
n <- readLn :: IO Int
points <- replicateM n (readPoint :: IO (Point Double))
let result = perimeter (Polygon points)
print result
I invite you to dissect this, and let me know if you have any questions at all. Functional programming is a tricky mindset to get into, because it's very different from other programming, but it's a handy set of techniques to have in your toolbelt.
If you need to treat the first iteration differently, it should be separated (if I understand your problem correctly). You can reduce duplication by using a helper function:
getNumLine :: IO [Int]
getNumLine = do
line <- getLine
return (map read (words line))
main = do
x <- readLn :: IO Int -- Double seemed wrong, use integer `div` below instead
firstline <- getNumLine
forM_ [2..x `div` 2] $ \lc -> do
...
And yes you could be much more "functional" about this, but I think it's best to learn in baby steps.
After everbodys help: my final solution:
import Data.List
import Data.Foldable
import Data.Traversable
import Data.List.Split
-- Calculate length of line given points x1,y2, x2,y2
calc_length:: Int -> Int -> Int -> Int -> Float
calc_length x1 y1 x2 y2 =
sqrt ( fromIntegral (height ^2 + width ^2) )
where height = abs( y2 - y1)
width = abs( x2 - x1)
-- Calculate the distances between vertex points (except the last)
getResults list =
sum [ calc_length (head f) (last f) (head s) (last s) | (f,s) <- (zip list (tail list)) ]
-- Calculate the last vertex distance between points
headAndTail list =
calc_length (z!!0) (z!!1) (z!!2) (z!!3)
where z = head list ++ last list
-- Prompt the user for co-ordinate pairs
main = do
x <- readLn :: IO Double
result <- forM [1,2..x ] ( \lc -> do
line1 <- getLine
let wds1 = map (\str -> read str::Int) (words $ line1)
return wds1)
print ( (getResults result) + (headAndTail result) )

Haskell - for loop

if I want to express something like [just a simple example]:
int a = 0;
for (int x = 0; x < n; x += 1)
a = 1 - a;
what should I do in Haskell, since it doesn't have variable concept? (maybe wrong, see: Does Haskell have variables?)
There are a few options. First, you can rewrite the problem with naive recursion:
loop :: Int -> Int
loop n = loop' n 0
where loop' 0 a = a
loop' n a = loop' (n - 1) (1 - a)
Next, you can restate recursion as a fold:
loop :: Int -> Int
loop n = foldr (\a _ -> 1 - a) 0 [0..n]
Or you can use State to simulate a for loop:
import Control.Monad
import Control.Monad.State
loop :: Int -> Int
loop n = execState (forM_ [0..n]
(\_ -> modify (\a -> 1 - a))) 0
Often, repetition that you would perform with a loop in a procedural language is accomplished with recursion in Haskell. In this case, you should think about what the result of the loop is. It appears to alternate between 0 and 1. There are several ways to do this in Haskell. One way is
alternatingList n = take n alternating0and1
alternating0and1 = 0 : alternating1and0
alternating1and0 = 1 : alternating0and1
In Haskell instead of using loops, you combine standard library functions and/or your own recursive function to achieve the desired effect.
In your example code you seem to be setting a to either 0 or 1 depending on whether or not n is even (in a rather confusing fashion if I'm honest). To achieve the same in Haskell, you'd write:
a =
if even n
then 0
else 1
Another option:
iterate (\a -> 1-a) 0 !! n
-- or even
iterate (1-) 0 !! n
The snippet iterate (\a -> 1-a) 0 produces an infinite lazy list of all the values obtained starting from 0 and repeatedly applying the function (\a -> 1-a). Then !! n takes the n-th element.
To be completely honest, in this case, I'd also look for a stricter definition of iterate which does not create so many lazy thunks.
The other answers have already explained how you would approach a problem like this functionally, in Haskell.
However, Haskell does have mutable variables (or references) in the form of ST actions and STRef. Using them is usually not very pretty, but it does allow you to express imperative, variable-mutating code faithfully in Haskell, if you really want to.
Just for fun, here's how you might use them to express your example problem.
(The following code also uses whileM_ from the monad-loops package, for convenience.)
import Control.Monad.Loops
import Control.Monad.ST
import Data.STRef
-- First, we define some infix operators on STRefs,
-- to make the following code less verbose.
-- Assignment to refs.
r #= x = writeSTRef r =<< x
r += n = r #= ((n +) <$> readSTRef r)
-- Binary operators on refs. (Mnemonic: the ? is on the side of the ref.)
n -? r = (-) <$> pure n <*> readSTRef r
r ?< n = (<) <$> readSTRef r <*> pure n
-- Armed with these, we can transliterate the original example to Haskell.
-- This declares refs a and x, mutates them, and returns the final value of a.
foo n = do
a <- newSTRef 0
x <- newSTRef 0
whileM_ (x ?< n) $ do
x += 1
a #= (1 -? a)
readSTRef a
-- To run it:
main = print =<< stToIO (foo 10)

What is the fastest way to initialize an immutable unboxed int array in Haskell?

Is this the fastest way to initialize an immutable array in Haskell with non-default (non-zero) values? In the following examples I am simply initializing the array with values from 0 to (size-1).
Fastest so far (twice the speed of Code.ST below). Thanks to leftaroundabout:
...
import qualified Data.Vector.Unboxed as V
stArray :: Int -> V.Vector Int
stArray size =
V.generate size id
...
My original fastest:
module Code.ST where
import Data.Array.MArray
import Data.Array.ST
import Data.Array.Unboxed
stArray :: Int -> UArray Int Int
stArray size =
runSTUArray $ newArray (0,size-1) 0 >>= f 0
where
f i a
| i >= size = return a
| otherwise = writeArray a i i >> f (i + 1) a
stMain :: IO ()
stMain = do
let size = 340000000
let a = stArray size
putStrLn $ "Size: " ++ show size ++ " Min: " ++ show (a ! 0) ++ " Max: " ++ show (a ! (size - 1))
I have tried the simpler immutable ways of doing it and it is 2 to 3 times slower on my PC (YMMV). I also tried Repa but it falls over even with smaller than 340000000 size arrays (lots of HD trashing - I gave up before it finished).
Have you tried listArray from Data.Array.Unboxed? You can use them like this:
-- listArray :: (Ix i, IArray a e) => (i, i) -> [e] -> a i e
listArray (0,3) "abcdefgh" :: UArray Int Char
This will create
array (0,3) [(0,'a'),(1,'b'),(2,'c'),(3,'d')]
If you need a bit more flexibility you can use array from the same module.
-- array :: (Ix i, IArray a e) => (i, i) -> [(i, e)] -> a i e
array (0,3) (zip [1,3,0,2] "abcd") :: UArray Int Char
Which will produce
array (0,3) [(0,'c'),(1,'a'),(2,'d'),(3,'b')]
I don't really know whether it is fast or not, but certainly it is more convenient to use than hand-written ST loops.

Erlang - how to "unflatten" an array

I'm new to Erlang, so this question might be a little basic.
I got an array with N^2 elements (I know N) which I want to break down into an array (or tuple, doesn't matter) with N tuples, each with N elements.
i.e: I want to turn:
[14,20,26,20,29,38,26,38,50]
into:
[ {14,20,26} , {20,29,38} , {26,38,50} }
Is there a simple way or a function that does this?
Thanks.
Use pattern matching:
s([X, Y, Z | Next]) ->
[{X, Y, Z} | s(Next)];
s([]) -> [].
This will fail if you don't supply a multiple of 3 elements, but that is probably what you want.
this should do what you want.
s(L,N) -> s(L,N,[]).
s([],_,R) -> lists:reverse;
s(L,N,R) ->
{L1,L2} = lists:split(N,L),
s(L2,[list_to_tuple(L1)|R]).
You can use this function sublist(List1, Start, Len) -> List2,
Returns the sub-list of List1 starting at Start and with (max) Len
elements. It is not an error for Start+Len to exceed the length of the
list.
unflatten(L, N) ->
case N*N == length(L) of
true -> unflatten_help(L, 1, N, []);
false ->
{error, "wrong list length!"}
end.
unflatten_help(_L, Start, N, Res) when Start == (N*N + 1) ->
lists:reverse(Res);
unflatten_help(L, Start, N, Res) ->
Temp = lists:sublist(L, Start, N),
unflatten_help(L, Start + N, N, [Temp | Res]).
main() ->
L = [14,20,26,20,29,38,26,38,50],
unflatten(L, 3).
The output:
[[14,20,26],[20,29,38],[26,38,50]]
I think the following code is fine for you:
array_to_tuples([],_) -> [];
array_to_tuples(L,N) ->
{L1,L2} = lists:split(N,L),
[list_to_tuple(L1)|array_to_tuples(L2,N)].
This will split your array, considering N*2 elements, in N tuples.

Resources