使用map在单个点评估许多函数

时间:2014-07-29 00:19:51

标签: map vectorization elm

我能够用Elm的share-elm.com制作一张漂亮的图片,我们会感谢任何有关代码优化的提示,但我会关注最后两行:

xflip : (number, number) -> (number, number)
xflip pt = ( -1*(fst pt), snd pt)

rot : (number, number) -> (number, number)
rot pt = ( -1*(snd pt), fst pt)

mul : number -> (number, number) -> (number, number)
mul a b = (a*(fst b), a*(snd b))

add : (number, number) -> (number, number) -> (number, number)
add a b = ((fst a)+(fst b), (snd a)+(snd b))

-- implementations of the symmetries of hilbert space curve

t1 : (number, number) -> (number, number)
t1 b = (add (mul 0.5 (-100,-100)) ((mul 0.5) (rot (rot(rot (xflip b))) )))

t2 : (number, number) -> (number, number)
t2 b = (add (mul 0.5 (-100,100)) ((mul 0.5) (b)))

t3 : (number, number) -> (number, number)
t3 b = (add (mul 0.5 (100,100)) ((mul 0.5) ( b)))

t4 : (number, number) -> (number, number)
t4 b = (add (mul 0.5 (100,-100)) ((mul 0.5) (rot (xflip b) )))

--

t : [(number, number)] -> [(number, number)]
t z = (map t1 z) ++ (map t2 z) ++ (map t3 z) ++ (map t4 z) 

我不知道这是否是定义矢量加法或2D变换的最佳选择,但我需要以某种方式进行。通常在图形本身上使用vector graphics,我会在它们成为Path类型之前处理点列表。

这是迭代旋转函数rot的最佳方法吗?我需要向左旋转90度然后向右旋转。所以我向左转3次:

rot (rot(rot (xflip b))) 

在主要问题上,我的最后两行可以简化:

t : [(number, number)] -> [(number, number)]
t z = (map t1 z) ++ (map t2 z) ++ (map t3 z) ++ (map t4 z) 

数字列表将成为我的Path个对象,t1t4是函数。我想也许我可以用map迭代这些函数。它适用于我在Github gist上尝试的案例:https://gist.github.com/MonsieurCactus/ef285584f1588289b477这是我尝试过的:

t : [(number, number)] -> [(number, number)]
t z = map ( \f -> (map f z)) [t1, t2, t3 ,t4]

Elm编译器返回错误消息:

[1 of 1] Compiling Main                ( Main.elm )
Type error on line 49, column 7 to 46:
        map (\f -> map f z) [t1,t2,t3,t4]

   Expected Type: (Float)
     Actual Type: _List

Type error on line 49, column 7 to 46:
        map (\f -> map f z) [t1,t2,t3,t4]

   Expected Type: Float
     Actual Type: (Float, Float)

也许我应该尝试编写一个函数[Path] -> [Path]但是我必须得到积分列表并改变它们。

1 个答案:

答案 0 :(得分:1)

简化最后两行

您缩短t定义的尝试是正确的方向。但是因为你映射了函数列表([t1,t2,t3,t4]),并且在映射函数内部映射了点z列表,最终得到了一个点列表列表({{1}而不是[[(number,number)]]) 所以你仍然需要concat列表列表。您也可以使用concatMap而不是宽松的[(number, number)]concat

map

迭代t : [(number, number)] -> [(number, number)] t z = concatMap ( \f -> (map f z)) [t1, t2, t3 ,t4]

如果您不介意使用rot而不是Float,则可以更改number功能以执行轮换。使用一些basic functions,您可以编写如下内容:

rot