gpt4 book ai didi

Haskell - 也许/只是递归

转载 作者:行者123 更新时间:2023-12-02 16:08:03 28 4
gpt4 key购买 nike

我读了一些关于 monad 的帖子和博客,也许,只是,什么都没有..但并没有真正明白:/在给定的代码中,我必须实现“latestActivity”函数。在我看来,它应该有效,但我不知道如何正确使用“Just”。也许有人能够帮助我。

module LatestActivity where
{-
Write a function 'latestActivity' that finds that last time a specific user
has sent a message. It is given a user name and a list of messages. A message
consists of the time it was sent, the user name of the user who sent it and
the message content. If there is no message from the given user in the list
the function yields 'Nothing'. Otherwise it yields 'Just' the latest time stamp
of the messages of that user in the list.
-}

import Data.List (sort)

-- | A time stamp represented as an 'Integer'
type AbsoluteTime = Integer
-- | A user name represented as a 'String'
type UserName = String

-- | A message consists of the time it was sent, the user who sent it
-- and the actual message content.
data Message = Message {
_timeStamp :: AbsoluteTime,
_userName :: UserName,
_messageContent :: String}

-- | Given a user name and a list of sent messages finds 'Just' the last time
-- a user has sent a message or 'Nothing' if the user has not sent anything.
-- The messages are not assumed to be ordered in any way.
latestActivity :: UserName -> [Message] -> Maybe AbsoluteTime
latestActivity _ [] = Nothing
latestActivity x y =
if (x == (_userName (last y))) -- x equals username in last list element?
then (_timeStamp (last y)) -- print it
else (latestActivity x init y) -- otherwise delete last listelement, recursion till list is empty

最佳答案

@rightfold 给出了一个可能的解决方案,但请注意,您的方法不是很惯用的 Haskell。 “否则删除最后一个列表元素”是程序思维,而不是您想要推理 Haskell 函数的方式。无论如何,这在你的代码中并没有真正发生,你不能在 Haskell 中删除东西,但需要每次迭代构建一个新列表:因此,它的效率非常低,因为 lastinit 在做其他事情之前需要遍历整个列表。

基本上,您所做的就是从后到前搜索列表。因此,显然要做的第一件事就是反转列表,以便您可以按照习惯从前到后进行搜索(并且列表已针对此进行了优化)。

latestActivity user = earliestAct . reverse
where earliestAct = ...

现在,这可以实现

  • 通过列表中简单的模式匹配递归:

       earliestAct [] = Nothing
    earliestAct (Message t user' txt : msgs)
    | user' == user = Just txt
    | otherwise = earliestAct msgs
  • 或者:正如我所说,这只是一个标准搜索。那么为什么不使用标准 find功能!

       earliestAct = fmap _messageContent . find ((==user) . _userName)

    在这里,我使用了 MaybeFunctor 实例从找到的消息中提取内容(如果有的话)。

关于Haskell - 也许/只是递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23934817/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com