"Pattern syntax in expression context" error - haskell

No idea what the problem is. Following exactly the hmatrix buildMatrix doc:
Prelude Data.Packed.Matrix> let k= buildMatrix 3 4 ( (r,c) -> fromIntegral r * fromIntegral c)
<interactive>:1:26:
Pattern syntax in expression context:
(r, c) -> fromIntegral r * fromIntegral c

In the docs, the markup wasn't properly escaped, it must be
let k = buildMatrix 3 4 (\(r,c) -> fromIntegral r * fromIntegral c)
The haddock markup was
{- | creates a Matrix of the specified size using the supplied function to
to map the row\/column position to the value at that row\/column position.
#> buildMatrix 3 4 (\ (r,c) -> fromIntegral r * fromIntegral c)
(3><4)
[ 0.0, 0.0, 0.0, 0.0, 0.0
, 0.0, 1.0, 2.0, 3.0, 4.0
, 0.0, 2.0, 4.0, 6.0, 8.0]#
Hilbert matrix of order N:
#hilb n = buildMatrix n n (\(i,j)->1/(fromIntegral i + fromIntegral j +1))#
-}
The backslashes need to be escaped for them to be displayed.

Related

Beginner to Haskell type system : "Haskell non-type variable argument in constraint" Error

In an attempt to dip my toes in functional programming, I'm attempting to pick up Haskell and running into some mental issues with the type system.
Running the following code gives proper output (e.g. generates coordinates for a circle wrapped around a cylinder of radius R at angle theta):
coilGeneration_AngleTest housingRadius coilWidth coilDepth numEle zoffset centralAngle
= [ (x',y',z)
| theta <- [0,2*pi/(numEle-1)..2*pi]
, let x = housingRadius * cos(coilWidth*cos(theta)/housingRadius)
, let y = housingRadius * sin(coilWidth*cos(theta)/housingRadius)
, let z = coilDepth * sin(theta)+zoffset
, let x' = x * cos(centralAngle) - y * sin(centralAngle)
, let y' = x * sin(centralAngle) + y * cos(centralAngle)
]
Sample coilGeneration_AngleTest function output
However, attempting to generalize this into a function that generates an arbitrary NxM array of circles with varying overlaps in the polar and z-directions by running:
coilArrayGeneration_Test r nE width depth n m mu gam
= [ (x',y',z',i,j)
| theta <- [0,2*pi/(nE-1)..2*pi]
, i <- [1..n]
, j <- [1..m]
, let a = width/2
, let b = depth/2
, let x = r * cos(a*cos(theta)/r)
, let y = r * sin(a*cos(theta)/r)
, let z = b * sin(theta)
, let phi = (2*i-1-n)((a-mu)/r)
, let zo = (2*j-1-m)(b-gam)
, let x' = x * cos(phi) - y * sin(phi)
, let y' = x * sin(phi) + y * cos(phi)
, let z' = z + zo
]
gives the following error:
Build profile: -w ghc-9.2.5 -O1
In order, the following will be built (use -v for more details):
- Haskell-0.1.0.0 (exe:Haskell) (file app/Main.hs changed)
Preprocessing executable 'Haskell' for Haskell-0.1.0.0..
Building executable 'Haskell' for Haskell-0.1.0.0..
[1 of 1] Compiling Main ( app/Main.hs, /Users/zack/Desktop/Udemy/Haskell/dist-newstyle/build/aarch64-osx/ghc-9.2.5/Haskell-0.1.0.0/x/Haskell/build/Haskell/Haskell-tmp/Main.o )
app/Main.hs:66:1: error:
• Non type-variable argument in the constraint: Num (c -> c)
(Use FlexibleContexts to permit this)
• When checking the inferred type
coilArrayGeneration_Test :: forall {c}.
(Floating c, Num (c -> c), Enum c, Enum (c -> c)) =>
c
-> c
-> c
-> c
-> (c -> c)
-> (c -> c)
-> c
-> c
-> [(c, c, c, c -> c, c -> c)]
|
66 | coilArrayGeneration_Test r nE width depth n m mu gam = [(x',y',z',i,j)|theta <- [0,2*pi/(nE-1)..2*pi],....
Failure Output
After googling for a while, it seemed that my function had an improper type implied by the compiler but I unfortunately don't understand the idea Haskell Type Definition well enough to fix it. I attempted to define the types the way I see them, namely:
r -> Double
nE -> Int
width -> Double
depth -> Double
n -> Int
m -> Int
mu -> Double
gam -> Double
x' -> Double
y' -> Double
z' -> Double
I -> Int
j -> Int
Getting:
coilArrayGeneration_Test :: (Floating a, Integral b) => a -> b -> a -> a -> b -> b -> a -> a -> [(a,a,a,b,b)]
coilArrayGeneration_Test r nE width depth n m mu gam
= [ (x',y',z',i,j)
| theta <- [0,2*pi/(nE-1)..2*pi]
, i <- [1..n]
, j <- [1..m]
, let a = width/2
, let b = depth/2
, let x = r * cos(a*cos(theta)/r)
, let y = r * sin(a*cos(theta)/r)
, let z = b * sin(theta)
, let phi = (2*i-1-n)((a-mu)/r)
, let zo = (2*j-1-m)(b-gam)
, let x' = x * cos(phi) - y * sin(phi)
, let y' = x * sin(phi) + y * cos(phi)
, let z' = z + zo
]
But this threw a whole host of errors:
Errors after Type Declaration
Which clearly means I don't know what I'm doing and mucked up the type declarations somehow.
Can anyone steer me the right way?
When you see a compiler error involving something like Num (c -> c), it never has anything to do with -XFlexibleContexts or with incorrect inferred types. It simply means you attempted to use something as a function which is not a function.
“Use as a function” entails simply that you have some expression of the form f x, where f and x can be arbitrary subexpressions. This includes in particular also expressions like (1+2)(3+4), which is the same as
let f = 1 + 2
x = 3 + 4
in f x
Presumably you meant to express multiplication by the juxtaposition. Well, use the multiplication operator then! I.e. (1+2)*(3+4).
Your code has also another problem: you trying to use the index variables in real-valued expression. Unlike the missing multiplication operators, this is fairly sensible, but Haskell doesn't allow this either. You need to explicitly wrap the integrals in fromIntegral.
coilArrayGeneration_Test r nE width depth n m μ γ
= [ (x',y',z',i,j)
| ϑ <- [0, 2*pi/fromIntegral(nE-1) .. 2*pi]
, i <- [1..n]
, j <- [1..m]
, let a = width/2
b = depth/2
x = r * cos(a*cos ϑ/r)
y = r * sin(a*cos ϑ/r)
z = b * sin ϑ
φ = fromIntegral(2*i-1-n) * ((a-μ)/r)
z₀ = fromIntegral(2*j-1-m) * (b-γ)
x' = x * cos φ - y * sin φ
y' = x * sin φ + y * cos φ
z' = z + z₀
]
I would strongly recommend you refactor this a bit, both code and types. 5-tuples are very obscure, you should at least wrap x,y,z in a suitable vector type.

Custom Data Type Filter - Any Numerical Type

import System.IO()
data Point = Point
{ pointX :: {-# UNPACK #-} !Double -- ^ X coordinate
, pointY :: {-# UNPACK #-} !Double -- ^ Y coordinate
} deriving (Show, Eq)
data Polygon = Polygon
{ points :: [Point]
, yvalue :: Int
} deriving (Show)
create a file test.hs
copy the two custom data type definitions above into it
open ghci and type :l test.hs
enter this test case:
*test> let a = Polygon {points = [Point {pointX = 0.0, pointY = 0.0},Point {pointX = 4.0, pointY = 0.0},Point {pointX = 4.0, pointY = 2.0},Point {pointX = 4.0, pointY = 4.0},Point {pointX = 0.0, pointY = 4.0},Point {pointX = 0.0, pointY = 2.0},Point {pointX = 0.0, pointY = 0.0}], yvalue = 2}
Then:
*test> let x = filter (<=(fromIntegral (yvalue a)).pointY) $ points a
You get the following error:
* couldn't match type `Point` with `Point -> c'
Expected type: [Point -> c]
Actual type: [Point]
* In the second argument of `($)', namely `points a'
In the expression:
filter (<=(fromIntegral (yvalue a)) . pointY) $ points a
In an equation for `x':
x = filter (<=(fromIntegral (yvalue a)).pointY) $ points a
* Relevant bindings include
x :: [Point -> c] (bound at <interactive>:92:5)
Solution is:
If you wish to filter by a specific numeric data type field then you just have to implement an instance of compare.
In my case:
instance Ord Point where
compare x y = compare (pointY x) (pointY y)
This set the specified field I wished to compare by to be pointY which was already an instance of Double.
I was then able to use the following filter:
filter(\x -> x > Point {pointX = 0.0, pointY = (fromIntegral(yvalue))} $ points a
Note: that the pointX in this filter is strictly irrelevant.
There may be another solution which arises as there are some brilliant Haskell Programmers here, but this one works.

Numerical issue with `foldl` and `foldr` in Haskell

I have the following Haskell script which computes the function f(x) = (2- x) - (2^3 - x^3/12)
calc x = (x - (x ^ 3) / 12)
calc2 x = (calc 2) - (calc x)
calcList1 :: [Float] -> Float
calcList1 l = foldl (+) 0.0 (map calc2 l)
calcList2 :: [Float] -> Float
calcList2 l = foldr (+) 0.0 (map calc2 l)
test1 :: Float -> Float
test1 step = (calcList1 l) - (calcList2 l)
where
l = [0.0,step..2.0]
Function calcList1 and calcList2 run calc2 function on each of list and then uses foldl and foldr respectively to sum the list. I was expecting both function to return the same answer but it does not.
*Main> test1 0.1
9.536743e-7
*Main> test1 0.01
2.2888184e-5
*Main> test1 0.001
2.4414063e-4
*Main> test1 0.0001
-3.7109375e-2
*Main>
Now I am confused. I can't see why numerical issues has to be involved here. Fold are essentially how ones collect each element which should be same in both cases, right?
In general, the order in which floating point values are added is important. An entry point for own research could be http://en.wikipedia.org/wiki/Loss_of_significance . To summarize the basic caveat, in an oversimplified form:
Due to the limited number of significant bits, you have to assume something like
100000000000000000.0 + 1.0 = 100000000000000000.0
in floating-point computations. Consequently, when computing
100000000000000000.0
+ 1.0
- 100000000000000000.0
the result will be 0.0 - and thus, be different from
100000000000000000.0
- 100000000000000000.0
+ 1.0
where the result will be 1.0.

Optimizing Perlin noise in Haskell

(Dependencies for this program: vector --any and JuicyPixels >= 2. Code is available as Gist.)
{-# LANGUAGE Haskell2010 #-}
{-# LANGUAGE BangPatterns #-}
import Control.Arrow
import Data.Bits
import Data.Vector.Unboxed ((!))
import Data.Word
import System.Environment (getArgs)
import qualified Codec.Picture as P
import qualified Data.ByteString as B
import qualified Data.Vector.Unboxed as V
I tried to port Ken Perlin's improved noise
to Haskell, but I'm not entirely sure that my method is correct. The main part
is something that should generalize nicely to higher and lower dimensions, but
that is something for later:
perlin3 :: (Ord a, Num a, RealFrac a, V.Unbox a) => Permutation -> (a, a, a) -> a
perlin3 p (!x', !y', !z')
= let (!xX, !x) = actuallyProperFraction x'
(!yY, !y) = actuallyProperFraction y'
(!zZ, !z) = actuallyProperFraction z'
!u = fade x
!v = fade y
!w = fade z
!h = xX
!a = next p h + yY
!b = next p (h+1) + yY
!aa = next p a + zZ
!ab = next p (a+1) + zZ
!ba = next p b + zZ
!bb = next p (b+1) + zZ
!aaa = next p aa
!aab = next p (aa+1)
!aba = next p ab
!abb = next p (ab+1)
!baa = next p ba
!bab = next p (ba+1)
!bba = next p bb
!bbb = next p (bb+1)
in
lerp w
(lerp v
(lerp u
(grad aaa (x, y, z))
(grad baa (x-1, y, z)))
(lerp u
(grad aba (x, y-1, z))
(grad bba (x-1, y-1, z))))
(lerp v
(lerp u
(grad aab (x, y, z-1))
(grad bab (x-1, y, z-1)))
(lerp u
(grad abb (x, y-1, z-1))
(grad bbb (x-1, y-1, z-1))))
This is of course accompanied by a few functions mentioned in the perlin3
function, of which I hope they are as efficient as possible:
fade :: (Ord a, Num a) => a -> a
fade !t | 0 <= t, t <= 1 = t * t * t * (t * (t * 6 - 15) + 10)
lerp :: (Ord a, Num a) => a -> a -> a -> a
lerp !t !a !b | 0 <= t, t <= 1 = a + t * (b - a)
grad :: (Bits hash, Integral hash, Num a, V.Unbox a) => hash -> (a, a, a) -> a
grad !hash (!x, !y, !z) = dot3 (vks `V.unsafeIndex` fromIntegral (hash .&. 15)) (x, y, z)
where
vks = V.fromList
[ (1,1,0), (-1,1,0), (1,-1,0), (-1,-1,0)
, (1,0,1), (-1,0,1), (1,0,-1), (-1,0,-1)
, (0,1,1), (0,-1,1), (0,1,-1), (0,-1,-1)
, (1,1,0), (-1,1,0), (0,-1,1), (0,-1,-1)
]
dot3 :: Num a => (a, a, a) -> (a, a, a) -> a
dot3 (!x0, !y0, !z0) (!x1, !y1, !z1) = x0 * x1 + y0 * y1 + z0 * z1
-- Unlike `properFraction`, `actuallyProperFraction` rounds as intended.
actuallyProperFraction :: (RealFrac a, Integral b) => a -> (b, a)
actuallyProperFraction x
= let (ipart, fpart) = properFraction x
r = if x >= 0 then (ipart, fpart)
else (ipart-1, 1+fpart)
in r
For the permutation group, I just copied the one Perlin used on his website:
newtype Permutation = Permutation (V.Vector Word8)
mkPermutation :: [Word8] -> Permutation
mkPermutation xs
| length xs >= 256
= Permutation . V.fromList $ xs
permutation :: Permutation
permutation = mkPermutation
[151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
]
next :: Permutation -> Word8 -> Word8
next (Permutation !v) !idx'
= v `V.unsafeIndex` (fromIntegral $ idx' .&. 0xFF)
And all this is tied together with JuicyPixels:
main = do
[target] <- getArgs
let image = P.generateImage pixelRenderer 512 512
P.writePng target image
where
pixelRenderer, pixelRenderer' :: Int -> Int -> Word8
pixelRenderer !x !y
= floor $ ((perlin3 permutation ((fromIntegral x - 256) / 32,
(fromIntegral y - 256) / 32, 0 :: Double))+1)/2 * 128
-- This code is much more readable, but also much slower.
pixelRenderer' x y
= (\w -> floor $ ((w+1)/2 * 128)) -- w should be in [-1,+1]
. perlin3 permutation
. (\(x,y,z) -> ((x-256)/32, (y-256)/32, (z-256)/32))
$ (fromIntegral x, fromIntegral y, 0 :: Double)
My problem is that perlin3 seems very slow to me. If I profile it, pixelRenderer
is getting a lot of time as well, but I'll ignore that for now. I don't know
how to optimize perlin3. I tried to hint GHC with bang patterns, which cuts
the execution time in half, so that's nice. Explicitly specializing and inlining
barely helps with ghc -O. Is perlin3 supposed to be this slow?
UPDATE: an earlier version of this question mentioned a bug in my code. This problem has been resolved; it turns out my old version of actuallyProperFraction was buggy. It implicitly rounded the integral part of a floating point number to Word8, and then subtracted it from the floating point number to get the fractional part. Since Word8 can only take values between 0 and 255 inclusive, this won't work properly for numbers outside that range, including negative numbers.
This code appears to be mostly computation-bound. It can be improved a little bit, but not by much unless there's a way to use fewer array lookups and less arithmetic.
There are two useful tools for measuring performance: profiling and code dumps. I added an SCC annotation to perlin3 so that it would show up in the profile. Then I compiled with gcc -O2 -fforce-recomp -ddump-simpl -prof -auto. The -ddump-simpl flag prints the simplified code.
Profiling: On my computer, it takes 0.60 seconds to run the program, and about 20% of execution time (0.12 seconds) is spent in perlin3 according to the profile. Note that the precision of my profile info is about +/-3%.
Simplifier output: The simplifier produces fairly clean code. perlin3 gets inlined into pixelRenderer, so that's the part of the output you want to look at. Most of the code consists of unboxed array reads and unboxed arithmetic. To improve performance, we want to eliminate some of this arithmetic.
An easy change is to eliminate the run-time checks on SomeFraction (which doesn't appear in your question, but is part of the code that you uploaded). This reduces the program's execution time to 0.56 seconds.
-- someFraction t | 0 <= t, t < 1 = SomeFraction t
someFraction t = SomeFraction t
Next, there are several array lookups that show up in the simplifier like this:
case GHC.Prim.indexWord8Array#
ipv3_s23a
(GHC.Prim.+#
ipv1_s21N
(GHC.Prim.word2Int#
(GHC.Prim.and#
(GHC.Prim.narrow8Word#
(GHC.Prim.plusWord# ipv5_s256 (__word 1)))
(__word 255))))
The primitive operation narrow8Word# is for coercing from an Int to a Word8. We can get rid of this coercion by using Int instead of Word8 in the definition of next.
next :: Permutation -> Int -> Int
next (Permutation !v) !idx'
= fromIntegral $ v `V.unsafeIndex` (fromIntegral idx' .&. 0xFF)
This reduces the program's execution time to 0.54 seconds. Considering just the time spent in perlin3, the execution time has fallen (roughly) from 0.12 to 0.06 seconds. Although it's hard to measure where the rest of the time is going, it's most likely spread out among the remaining arithmetic and array accesses.
On my machine reference code with Heatsink's optimisations takes 0.19 secs.
Firstly, I has moved from JuicyPixels to yarr and yarr-image-io with my favourite flags, -Odph -rtsopts -threaded -fno-liberate-case -funbox-strict-fields -fexpose-all-unfoldings -funfolding-keeness-factor1000 -fsimpl-tick-factor=500 -fllvm -optlo-O3 (they are given here):
import Data.Yarr as Y
import Data.Yarr.IO.Image as Y
...
main = do
[target] <- getArgs
image <- dComputeS $ fromFunction (512, 512) (return . pixelRenderer)
Y.writeImage target (Grey image)
where
pixelRenderer, pixelRenderer' :: Dim2 -> Word8
pixelRenderer (y, x)
= floor $ ((perlin3 permutation ((fromIntegral x - 256) / 32,
(fromIntegral y - 256) / 32, 0 :: Double))+1)/2 * 128
-- This code is much more readable, but also much slower.
pixelRenderer' (y, x)
= (\w -> floor $ ((w+1)/2 * 128)) -- w should be in [-1,+1]
. perlin3 permutation
. (\(x,y,z) -> ((x-256)/32, (y-256)/32, (z-256)/32))
$ (fromIntegral x, fromIntegral y, 0 :: Double)
This makes the program 30% faster, 0.13 seconds.
Secondly I has replaced uses of standard floor with
doubleToByte :: Double -> Word8
doubleToByte f = fromIntegral (truncate f :: Int)
It is known issue (google "haskell floor performance"). Execution time is reduced to 52 ms (0.052 secs), in almost 3 times.
Finally, just for fun I tried to compute noise in parallel (dComputeP instead of dComputeS and +RTS -N4 in command line run). Program took 36 ms, including I/O constant of about 10 ms.

Cartesian Plane

I'm trying to define a function in Haskell that takes an integer argument c and returns the list of all points on the cartesian plane of the form (x/c,y/c) where x and y are integers.
x/c is between -2 and 1 and y/r is between -1 and 1
This is what I've gotten so far which I'm almost sure is right but I'm getting a parse error on input = when I run it particularly at this line: cart xs ys c = [(y/c,x/c) | x <- xs, y <- ys]
plane :: Int -> [a]
plane c = cart [-1*c .. 1*c] [-2*c .. 1*c] c
cart xs ys c = [(y/c,x/c) | x <- xs, y <- ys]
A sample output would be: plane 1 would generate:
[(-2.0, -1.0), (-1.0, -1.0), ( 0.0, -1.0), ( 1.0, -1.0),
(-2.0, 0.0), (-1.0, 0.0), ( 0.0, 0.0), ( 1.0, 0.0),
(-2.0, 1.0), (-1.0, 1.0), ( 0.0, 1.0), ( 1.0, 1.0)]
Anyone have any idea how I can fix this! Thanks
you are missing the where, other than that it looks like you have some type errors.
[a] is too general
/ only works on fractional types.
so
plane :: Int -> [(Int,Int)]
plane c = cart [-1*c .. 1*c] [-2*c .. 1*c] c where
cart xs ys c = [(y `div` c,x `div` c) | x <- xs, y <- ys]
might be what you want. Smallest change from what you have that more or less works.
This is how I'd do it. fromintegral is a type 'glue' function that converts any value in the Integral type class to any other type in the Num typeclass. The result type has to be in RealFrac (like Double or Rational) to use the / operator.
plane :: (Integral a, RealFrac b) => a -> [(b,b)]
plane d = [(fI y / fI d,fI x / fI d) | x <- [-2*d..d], y <- [-d..d]]
where fI = fromIntegral

Resources