在 Elm 中从 LinkedList 的尾部移除(对比 JavaScript)
Removing from Tail on LinkedList in Elm (vs JavaScript)
我认识到这可能不是 JavaScript 中链表的精确实现,但这是我所拥有的:
// a Node is either null or { value: value, next: Node }
function createNode(value) {
return { value: value, next: null };
}
function isEmpty(node) {
return node === null;
}
function addToHead(value, node) {
var newNode = createNode(value);
newNode.next = node;
return newNode;
}
function addToTail(value, node) {
var newNode = createNode(value);
if (isEmpty(node)) return newNode;
node.next = addToTail(value, node.next);
return node;
}
function contains(value, node) {
if (isEmpty(node)) return false;
if (node.value === value) return true;
return contains(value, node.next);
}
function removeFromTail(node) {
if (isEmpty(node) || isEmpty(node.next)) return null;
var current = node;
var next = current.next;
while (next.next) {
current = next;
next = next.next;
}
current.next = null;
return node;
}
我的问题是您将如何在 Elm 中实现 removeFromTail 代码 - 特别是我的代码涉及突变和重新绑定引用。
这是在 Elm 中的部分重新实现:
type List a = Empty | Node a (List a)
addToHead value list =
case list of
Empty ->
Node value Empty
Node _ _ ->
Node value list
contains value list =
case list of
Empty ->
False
Node v sublist ->
if v == value then
True
else
contains value sublist
但是,我卡在了 addToTail 和 removeFromTail 上,因为我不确定如何在不重建新列表的情况下执行此操作。
在不可变链表的尾部进行操作意味着需要重建链表。没有办法解决这个问题。
由于 List a
是内置的 Elm 类型,我还建议更改名称以避免名称冲突。
type MyList a = Empty | Node a (MyList a)
addToTail
然后是给定一个新的最后一项的项目的问题:
addToTail : a -> MyList a -> MyList a
addToTail val list =
case list of
Empty -> Node val Empty
Node x xs -> Node x <| addToTail val xs
删除最后一项可以通过返回包含最后一项和新列表的元组来完成。可以通过映射 Maybe 值来构建新列表(引入 Maybe 是因为您无法获取空列表的最后一项):
removeFromTail : MyList a -> Maybe (a, MyList a)
removeFromTail list =
case list of
Empty -> Nothing
Node x Empty -> Just (x, Empty)
Node x xs -> Maybe.map (\(y, ys) -> (y, Node x ys)) <| removeFromTail xs
我认识到这可能不是 JavaScript 中链表的精确实现,但这是我所拥有的:
// a Node is either null or { value: value, next: Node }
function createNode(value) {
return { value: value, next: null };
}
function isEmpty(node) {
return node === null;
}
function addToHead(value, node) {
var newNode = createNode(value);
newNode.next = node;
return newNode;
}
function addToTail(value, node) {
var newNode = createNode(value);
if (isEmpty(node)) return newNode;
node.next = addToTail(value, node.next);
return node;
}
function contains(value, node) {
if (isEmpty(node)) return false;
if (node.value === value) return true;
return contains(value, node.next);
}
function removeFromTail(node) {
if (isEmpty(node) || isEmpty(node.next)) return null;
var current = node;
var next = current.next;
while (next.next) {
current = next;
next = next.next;
}
current.next = null;
return node;
}
我的问题是您将如何在 Elm 中实现 removeFromTail 代码 - 特别是我的代码涉及突变和重新绑定引用。
这是在 Elm 中的部分重新实现:
type List a = Empty | Node a (List a)
addToHead value list =
case list of
Empty ->
Node value Empty
Node _ _ ->
Node value list
contains value list =
case list of
Empty ->
False
Node v sublist ->
if v == value then
True
else
contains value sublist
但是,我卡在了 addToTail 和 removeFromTail 上,因为我不确定如何在不重建新列表的情况下执行此操作。
在不可变链表的尾部进行操作意味着需要重建链表。没有办法解决这个问题。
由于 List a
是内置的 Elm 类型,我还建议更改名称以避免名称冲突。
type MyList a = Empty | Node a (MyList a)
addToTail
然后是给定一个新的最后一项的项目的问题:
addToTail : a -> MyList a -> MyList a
addToTail val list =
case list of
Empty -> Node val Empty
Node x xs -> Node x <| addToTail val xs
删除最后一项可以通过返回包含最后一项和新列表的元组来完成。可以通过映射 Maybe 值来构建新列表(引入 Maybe 是因为您无法获取空列表的最后一项):
removeFromTail : MyList a -> Maybe (a, MyList a)
removeFromTail list =
case list of
Empty -> Nothing
Node x Empty -> Just (x, Empty)
Node x xs -> Maybe.map (\(y, ys) -> (y, Node x ys)) <| removeFromTail xs