如何链接haskell中可能的参数的使用? [英] How to chain the use of maybe argument in haskell?

查看:87
本文介绍了如何链接haskell中可能的参数的使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从可选参数中构建一个字符串。例如,从标题和名称生成欢迎字符串这在命令式语言中是微不足道的,看起来像这样

  def如果a:
s + =Mr
if b:
s + = b

我在haskell中的第一次尝试是:

  greeting :: Bool->可能是String  - >字符串
问候标题名称= foldl(++)Hello(catMaybes [title'title,name])
where
title'True = JustMr
title' False = Nothing

我确信有一种方法可以做到这一点。首先,我确定这个 foldl catMaybes 组合存在于某处,但我找不到它。其次,折叠在这里工作,因为我使用相同的操作(和相同的类型)。那么有什么更好的方法来做到这一点?
我也在考虑使用Writer,但我不知道如何去做。



更新



这只是一个例子(可能不好或太简单)。我的问题更多,如何将它推广到许多参数。



所以真正的问题不仅在于串联2个字符串,更在于如何通过可选的模板生成字母部分和参数,就像你在Word中使用邮件合并工具一样。

数量,过期时间等等。某些字段可以是可选的。另一方面,您有一个模板,目标是根据*模板为每个客户(行)生成一个字母。问题是,你如何在haskell中编写这个模板(没有任何模板库的帮助)。
在我的第一个例子中,模板将是hello(Mr){name},但实际上这个模板可以在发票,声明函甚至完整的会计报告中。

$ b $ Haskell非常擅长抽象,它可以很容易地复制命令式样。你在你的例子中所做的就是所谓的构建器模式。 Writer 是一个monad,它包装了任何 Monoid 数据和 String Monoid

  import Control.Monad.Writer hiding(forM_)
import Data.Foldable

greeting :: Bool - >可能是String - >字符串 - >字符串
问候先生姓名=
execWriter $做
告诉$你好,
当先生告诉$先生
forM_ name $ \s - >告诉$++ s
告诉$++姓氏
告诉$!

main = do
putStrLn $ greeting False(只是Ray)Charles
putStrLn $ greeting True NothingBean



输出:

  Ray Charles! 
你好,比恩先生!


I'm trying to build a string from optional arguments. For example to generate a greeting string from a title and a name This is trivial in a imperative language and would look like this

def greeting(title, name):
   s = "Hello"
   if a :
        s += "Mr"
   if b: 
        s += b

My first attempt in haskell is :

greeting :: Bool-> Maybe String -> String
greeting title name = foldl (++) "Hello" (catMaybes [title' title, name])
   where
   title' True = Just "Mr"
   title' False = Nothing

I'm sure there is a bette way to do it. First, I'm sure this foldl catMaybes combination exists somewhere but I couldn't find it. Second, folding works here because I'm using the same operation (and the same type). So what is there a better way to do it ? I was also thinking using a Writer but I'm not sure either how to do it.

Update

This is only an example (maybe bad or too simple). My question is more , how to generalize it to many arguments .

So the real problem is not just about concatening 2 strings but more how to generate letters from a template with optional sections and parameters, like you would do in Word with the mail merge tool.

You have on one a csv file with customer name, telephone number, how much is overdue etc. Some of the field could be optional. On the other side you have a template and the goal is to generate one letter per customer (row) according to the *template. The question is then how do you write this template in haskell (without the help of any templating library). In my first example the template will be "hello (Mr){name}" but in the real word the template could be in invoice, a statement letter or even a complete accounting report.

解决方案

Haskell is so good at abstractions, it can easily replicate the imperative patterns. What you're doing in your example is called a "builder" pattern. Writer is a monad, which wraps a pattern of accumulation or "building" of any Monoid data, and String is a Monoid.

import Control.Monad.Writer hiding (forM_)
import Data.Foldable

greeting :: Bool -> Maybe String -> String -> String
greeting mr name surname = 
  execWriter $ do
    tell $ "Hello,"
    when mr $ tell $ " Mr."
    forM_ name $ \s -> tell $ " " ++ s
    tell $ " " ++ surname
    tell $ "!"

main = do
  putStrLn $ greeting False (Just "Ray") "Charles"
  putStrLn $ greeting True Nothing "Bean"

Outputs:

Hello, Ray Charles!
Hello, Mr. Bean!

这篇关于如何链接haskell中可能的参数的使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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