将列表映射到转移的自我
Map List onto shifted self
我终于找到了使用 elm 进行函数式编程的绝佳切入点,天哪,我喜欢它吗,但我仍然缺乏一些关于一些概念的基本优雅。
我经常发现自己编写的代码类似于下面的代码,这似乎是在做它应该做的,但是如果有经验的人可以建议一种更紧凑和直接的方法,我相信这可以提供一些有价值的见解这真(u)rcery.
我想这可以归结为如下内容
(<->
是向量减法运算符):
edgeDirections : List Vector -> List Vector
edgeDirections corners = List.map2 (\p v -> p <-> v) corners (shiftr 1 corners)
但我并没有真正令人满意的方法来完成 shiftr
的方法。
但 Whosebug 的规则要求它,这是我尝试过的。我写了一个 shiftr
可能用法的丑陋示例(我绝对不喜欢 Debug.crash
并且我对 Maybe
不满意):
给定一个向量列表(多边形的角点),通过计算每个角向量与其前一个角向量的差异来计算方向向量,从第一个和最后一个条目之间的差异开始列表。
[v1,v2,v3] -> [v1-v3,v2-v1,v3-v2]
这里是:
edgeDir : Vector -> ( Maybe Vector, List Vector ) -> ( Maybe Vector, List Vector )
edgeDir p ( v, list ) =
case v of
Nothing ->
Debug.crash ("nono")
Just vector ->
( Just p, list ++ [ p <-> vector ] )
edgeDirections : List Vector -> List Vector
edgeDirections corners =
let
last =
List.head <| List.reverse corners
in
snd <| List.foldl edgeDir ( last, [] ) corners
main =
show <| edgeDirections [ Vector -1 0, Vector 0 1, Vector 1 0 ]
我很欣赏任何关于如何以更直接的方式实现这一结果的见解,可能使用我还不知道的现有语言结构,或者关于如何减轻 Maybe
痛苦的任何指示。后者可能 Just
不可能,但我确信前者会 a) 让我震惊 b) 让我挠头几次 :)
谢谢您,非常感谢您使用这种恰当的语言!
就在我 "hung up" 之后,我想到了这个,但我相信如果它是正确的(并且它只适用于 n=1),我相信它仍然可以大大改进
shiftr : List a -> List a
shiftr list =
let
rev =
List.reverse list
in
case List.head rev of
Nothing ->
list
Just t ->
[ t ] ++ (List.reverse <| List.drop 1 rev)
main =
show (shiftr [ 1, 2, 3, 4 ] |> shiftr)
如果 Elm 有内置的 init
and last
函数,这可能会更干净。
您可以通过进行一些模式匹配来摆脱所有这些 Maybe。这是我仅使用模式匹配和累加器的尝试。
import List exposing (map2, append, reverse)
shiftr list =
let shiftr' acc rest =
case rest of
[] -> []
[x] -> x :: reverse acc
(x::xs) -> shiftr' (x::acc) xs
in shiftr' [] list
edgeDirections vectors =
map2 (<->) vectors <| shiftr vectors
还要注意(<->)
的映射函数的简写,相当于(\p v -> p <-> v)
.
假设 Elm did 有一个 init
和 last
函数——让我们在这里快速定义它们:
init list =
case list of
[] -> Nothing
[_] -> Just []
(x::xs) -> Maybe.map ((::) x) <| init xs
last list =
case list of
[] -> Nothing
[x] -> Just x
(_::xs) -> last xs
然后您的 shiftr
函数可以缩短为:
shiftr list =
case (init list, last list) of
(Just i, Just l) -> l :: i
_ -> list
我终于找到了使用 elm 进行函数式编程的绝佳切入点,天哪,我喜欢它吗,但我仍然缺乏一些关于一些概念的基本优雅。
我经常发现自己编写的代码类似于下面的代码,这似乎是在做它应该做的,但是如果有经验的人可以建议一种更紧凑和直接的方法,我相信这可以提供一些有价值的见解这真(u)rcery.
我想这可以归结为如下内容
(<->
是向量减法运算符):
edgeDirections : List Vector -> List Vector
edgeDirections corners = List.map2 (\p v -> p <-> v) corners (shiftr 1 corners)
但我并没有真正令人满意的方法来完成 shiftr
的方法。
但 Whosebug 的规则要求它,这是我尝试过的。我写了一个 shiftr
可能用法的丑陋示例(我绝对不喜欢 Debug.crash
并且我对 Maybe
不满意):
给定一个向量列表(多边形的角点),通过计算每个角向量与其前一个角向量的差异来计算方向向量,从第一个和最后一个条目之间的差异开始列表。
[v1,v2,v3] -> [v1-v3,v2-v1,v3-v2]
这里是:
edgeDir : Vector -> ( Maybe Vector, List Vector ) -> ( Maybe Vector, List Vector )
edgeDir p ( v, list ) =
case v of
Nothing ->
Debug.crash ("nono")
Just vector ->
( Just p, list ++ [ p <-> vector ] )
edgeDirections : List Vector -> List Vector
edgeDirections corners =
let
last =
List.head <| List.reverse corners
in
snd <| List.foldl edgeDir ( last, [] ) corners
main =
show <| edgeDirections [ Vector -1 0, Vector 0 1, Vector 1 0 ]
我很欣赏任何关于如何以更直接的方式实现这一结果的见解,可能使用我还不知道的现有语言结构,或者关于如何减轻 Maybe
痛苦的任何指示。后者可能 Just
不可能,但我确信前者会 a) 让我震惊 b) 让我挠头几次 :)
谢谢您,非常感谢您使用这种恰当的语言!
就在我 "hung up" 之后,我想到了这个,但我相信如果它是正确的(并且它只适用于 n=1),我相信它仍然可以大大改进
shiftr : List a -> List a
shiftr list =
let
rev =
List.reverse list
in
case List.head rev of
Nothing ->
list
Just t ->
[ t ] ++ (List.reverse <| List.drop 1 rev)
main =
show (shiftr [ 1, 2, 3, 4 ] |> shiftr)
如果 Elm 有内置的 init
and last
函数,这可能会更干净。
您可以通过进行一些模式匹配来摆脱所有这些 Maybe。这是我仅使用模式匹配和累加器的尝试。
import List exposing (map2, append, reverse)
shiftr list =
let shiftr' acc rest =
case rest of
[] -> []
[x] -> x :: reverse acc
(x::xs) -> shiftr' (x::acc) xs
in shiftr' [] list
edgeDirections vectors =
map2 (<->) vectors <| shiftr vectors
还要注意(<->)
的映射函数的简写,相当于(\p v -> p <-> v)
.
假设 Elm did 有一个 init
和 last
函数——让我们在这里快速定义它们:
init list =
case list of
[] -> Nothing
[_] -> Just []
(x::xs) -> Maybe.map ((::) x) <| init xs
last list =
case list of
[] -> Nothing
[x] -> Just x
(_::xs) -> last xs
然后您的 shiftr
函数可以缩短为:
shiftr list =
case (init list, last list) of
(Just i, Just l) -> l :: i
_ -> list