Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell-可能/只是递归_Haskell_Monads_Maybe - Fatal编程技术网

Haskell-可能/只是递归

Haskell-可能/只是递归,haskell,monads,maybe,Haskell,Monads,Maybe,我读了一些关于monads的帖子和博客,也许,只是,没什么。。但并没有真正理解:/ 在给定的代码中,我必须实现“latestActivity”函数。 在我看来,它应该会起作用,但我不知道如何正确使用“Just”。也许有人能帮我 module LatestActivity where {- Write a function 'latestActivity' that finds that last time a specific user has sent a message. It is giv

我读了一些关于monads的帖子和博客,也许,只是,没什么。。但并没有真正理解:/ 在给定的代码中,我必须实现“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

只需添加…
只需添加
:v

latestActivity :: UserName -> [Message] -> Maybe AbsoluteTime
latestActivity _ [] = Nothing 
latestActivity x y = 
    if x == _userName (last y)
        then Just (_timeStamp (last y))
        else latestActivity x (init y)

@rightfold提供了一个可能的解决方案,但请注意,您的方法不是非常惯用的Haskell。“否则删除最后一个listelement”是一种过程性思维,而不是您想要对Haskell函数进行推理的方式。无论如何,这在代码中并没有真正发生,您不能删除Haskell中的内容,但每次迭代都需要构建一个新列表:因此,它的效率极低,因为
last
init
都需要遍历整个列表,然后才能执行其他操作

基本上,你要做的是从列表中搜索,从后到前。因此,显而易见,首先要做的是,颠倒列表,这样你就可以按照习惯从前到后搜索(而且列表已经优化了)

现在,这也可以实现

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

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

       earliestAct = fmap _messageContent . find ((==user) . _userName)
    
    这里,我使用了
    Maybe
    Functor
    实例从找到的消息中提取内容(如果有的话)


这不应该是
否则最新活动x(初始y)
?天哪。。我已经试着在那个位置上加上“Just”,但没用。。所以在纠正括号后,你的做法很好。谢谢你的回答!你是对的!但我是个初学者,刚刚完成了几项任务,如果它能奏效,我很高兴——不管它有多有效,我真的需要摆脱这种思维方式。。THXY您应该提供当前解决方案存在哪些问题的更多详细信息,例如从编译器收到的任何错误消息或运行时的错误行为。如果没有这些信息,人们看到你做错了什么并帮助你会花费更多的时间。
   earliestAct = fmap _messageContent . find ((==user) . _userName)