Haskell:引用更新函数中以前更新的列表元素 [英] Haskell : reference to previously updated elements of list within the update function
问题描述
假设我有以下定义:
pre $ data Book = Book {id :: Int,title :: String}
type Shelf = [Book]
假设我有一个假设的函数(upd用于更新)
updShelf :: Shelf - >书架
updShelf all @(book:books)= updBook book:updShelf books
所有罚款至今。现在我们假设updateBook函数需要在它之前引用 更新的 三本书,也就是说,书架中位置5的book的updateBook需要参考位置2的book(假设前三本书不需要这样的参考来更新)。没问题,我说,并修改我的代码:
updShelf :: Shelf - >书架
updShelf所有@(书:书)prevBook = updBook书prevBook:updShelf书
其中prevBook = ???
我需要帮助的是prevBook函数。虽然我甚至不确定我是否以正确的方式处理这个问题。所以,如果你们有更好的建议来解决这个问题,我们将非常感激。
编辑:
< Thomas M. DuBuisson:您的解决方案不适用于我。这是为什么:
假设初始货架(全部)状态为
Book {id = 1,title =a }
Book {id = 2,title =b}
Book {id = 3,title =c}
Book {id = 4,title =d}
Book {id = 5,title =e}
Book {id = 6,title =f}
Book {id = 7,title =g} $ b $ (book){b = Book {title =h}
然后(drop 3 partialUpdate)是
updBook 4
updBook 5
updBook 6
updBook 7
updBook 8
zipWith'($)(drop 3 partialUpdate)(所有)是:
updBook 4 1
updBook 5 2
updBook 6 3
updBook 7 4 - >哎呀!旧版本的书4!
updBook 8 5 - >哎呀!旧版本的书5!
在我的情况中,我需要书籍7和8根据已更新版本的书4进行更新, 5,而不是未更新的。我希望你明白我的意思。
.haskell.org/haskellwiki/Tying_the_Knot>绑结:我们将在计算答案时使用答案。出于说明的目的,我将使用 type Book = Int
来替代。 updateShelf :: Shelf - >货架
updateShelf shelf = answer其中
answer = zipWith updateBook移动货架
移动=复制3 Nothing ++ map只需回答
- 一些愚蠢的实现只是为了说明
updateBook ::可能预订 - >书 - > Book
updateBook Nothing current = current + 1
updateBook(Just threeBack)current = current + threeBack + 1
现在,在 ghci
中,我们可以验证 updateShelf
确实在使用更新的版本:
*主要> updateShelf [1,10,100,1000,10000]
[2,11,101,1003,10012]
<正如你所看到的,前三个是 1 + 1
, 10 + 1
和 100 + 1
,其余两个是 1000+(1 + 1)+1
和 10000+( 10 + 1)+1
,因此正如你所希望的那样使用更新的以前的值。
Say I have the following definitions
data Book = Book {id :: Int, title :: String}
type Shelf = [Book]
Assuming I have a hypothetical function (upd is for update)
updShelf :: Shelf -> Shelf
updShelf all@(book : books) = updBook book : updShelf books
All fine so far. Now let's say the updateBook function needs to refer to the updated book three books before it i.e updateBook for book at position 5 in bookshelf need to refer to book at position 2 (assume first three books need no such reference to update). No problem, I say, and modify my code as such:
updShelf :: Shelf -> Shelf
updShelf all@(book : books) prevBook = updBook book prevBook : updShelf books
where prevBook = ???
What I need help is with is the prevBook function. Although I am not even sure if I am approaching this problem the right way. So, if you guys have any better suggestion to approach this problem differently, it would be highly appreciated
EDIT:
Thomas M. DuBuisson: Your solution won't work for me. Here's why: Assume initial shelf (all) state as
Book {id=1, title="a"}
Book {id=2, title="b"}
Book {id=3, title="c"}
Book {id=4, title="d"}
Book {id=5, title="e"}
Book {id=6, title="f"}
Book {id=7, title="g"}
Book {id=8, title="h"}
then (drop 3 partialUpdate) is (using only ids rather than entire book statement):
updBook 4
updBook 5
updBook 6
updBook 7
updBook 8
zipWith' ($) (drop 3 partialUpdate) (all) is :
updBook 4 1
updBook 5 2
updBook 6 3
updBook 7 4 -> YIKES! Older version of book 4!
updBook 8 5 -> YIKES! Older version of book 5!
In my case, I need books 7 and 8 to be updated against already updated versions of book 4 and 5,not the un-updated ones. I hope you understand what I mean to convey.
This trick is related to tying the knot: we'll use the answer while computing the answer. For the purposes of illustration, I'll use type Book = Int
instead.
updateShelf :: Shelf -> Shelf
updateShelf shelf = answer where
answer = zipWith updateBook shifted shelf
shifted = replicate 3 Nothing ++ map Just answer
-- some stupid implementation just for illustration
updateBook :: Maybe Book -> Book -> Book
updateBook Nothing current = current + 1
updateBook (Just threeBack) current = current + threeBack + 1
Now, in ghci
, we can verify that updateShelf
is really using the updated versions:
*Main> updateShelf [1,10,100,1000,10000]
[2,11,101,1003,10012]
As you can see, the first three are 1+1
, 10+1
, and 100+1
, and the remaining two are 1000+(1+1)+1
and 10000+(10+1)+1
, and are therefore using the updated previous values, just as you'd hope.
这篇关于Haskell:引用更新函数中以前更新的列表元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!