Haskell最佳实践:在Haskeline中提前终止 [英] Haskell Best Practise: Early termination in Haskeline

查看:250
本文介绍了Haskell最佳实践:在Haskeline中提前终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Haskeline 包,我想从中获取三个字符串在我做任何事情之前的命令行,我已经想出了对我来说似乎是一个很好的解决方案。但我相信可能有更好的方法来做到这一点。我在使用Haskeline软件包时寻找最佳实践。请评估以下示例代码的优点:

  import System.Console.Haskeline 
import Control.Monad.Trans
import Control.Monad.Maybe
import Data.Maybe
import Control.Monad
$ b $ main :: IO()
main = runInputT defaultSettings(runMaybeT getStrings)>> = print

getStrings :: MaybeT(InputT IO)(String,String,String)
getStrings = do
mone< - lift $ getInputLine食品>
notNothing mone
mtwo< - lift $ getInputLinedrink>
notNothing mtwo
mthree< - lift $ getInputLinedessert>
notNothing mthree
return(fromJust mone,fromJust mtwo,fromJth mthree)
where
notNothing a = guard(a / = Nothing)

您可以看到它完成了提前终止的任务,但它看起来仍然有点不自然。我正在考虑尝试将notNothing和getInputLine转换为一行,如下所示:

  mone<  -  notNothing =< ;< lift $ getInputLinefood> - 不检查

我认为这看起来并不好。我认为这是非常清晰和简洁的(尽管它没有输入检查,所以我将不得不编写一个版本)。



然而,这是我拥有的最好的拿出来,我的问题最后是:你会如何改善这个代码更整洁,更容易阅读?我甚至在正确的轨道上吗?



编辑:如果你的警卫不是'a / = Nothing'我发现的是:

$ p $ myGuard s = guard(someConditionFunc s)>> s

因为您可以编写(如):

  mone < -  myGuard =<< (lift $ getInputLine提示符)

这非常酷。但是,如果你仅仅匹配Nothing,那么TomMD的答案会更好。

解决方案为什么不利用<$ c $对于Maybe monad,c> fail _ = Nothing

  mthree < -  lift $ getInputLine甜点>
notNothing mthree

变成

 只需要mthree<  -  lift $ getInputLinedessert>


I am using the Haskeline package and I want to get three strings in a row from the command line before I do anything and I have come up with what seems to be a neat solution to me. But I am sure that there might be a better way to do it. I am looking for best practices while using the Haskeline package. Please evaluate the merits of the following example code:

import System.Console.Haskeline
import Control.Monad.Trans
import Control.Monad.Maybe
import Data.Maybe
import Control.Monad

main :: IO ()
main = runInputT defaultSettings (runMaybeT getStrings) >>= print

getStrings :: MaybeT (InputT IO) (String, String, String)
getStrings = do
   mone <- lift $ getInputLine "food> "
   notNothing mone
   mtwo <- lift $ getInputLine "drink> "
   notNothing mtwo
   mthree <- lift $ getInputLine "dessert> "
   notNothing mthree
   return (fromJust mone, fromJust mtwo, fromJust mthree)
      where
         notNothing a = guard (a /= Nothing)

As you can see it accomplishes the task of early termination but it looks a bit yucky still. I'm thinking of trying to convert the notNothing's and the getInputLine's into a single line like:

mone <- notNothing =<< lift $ getInputLine "food> " -- does not type check

Which I think does not look that bad. I think that is pretty clear and concise (though it does not type check so I will have to write a version that does).

However, this is the best I have come up with and my question finally is: How would you go about improving this code to be neater and more readily readable? Am I even on the right track?

Edit: If your guard is something other than 'a /= Nothing' then a nice helper function that I just discovered is:

myGuard s = guard (someConditionFunc s) >> s

Because then you can write (as luqui suggested):

mone <- myGuard =<< (lift $ getInputLine prompt)

Which is pretty cool. But if you are matching against only Nothing then TomMD's answer is better.

解决方案

Why not just leverage the fact that fail _ = Nothing for the Maybe monad?

mthree <- lift $ getInputLine "dessert> "
notNothing mthree

becomes

Just mthree <- lift $ getInputLine "dessert> "

这篇关于Haskell最佳实践:在Haskeline中提前终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆