haskell中的符号

时间:2018-04-27 12:26:33

标签: haskell

所以我试图在haskell中编写一个函数,它执行以下操作: 1.输入是一个字符串 2.函数首先删除字符串的所有字母,只保留数字 3.函数将字符串数转换为int数 4.函数将字符串中的数字相加并打印出来

我的代码直到'第3步

func str = 
    do 
    str <- filter (< 'a') str
    str2 <- map digitToInt str
    return str2

如果我用mapToInt删除第4行它不会起作用,直到步骤#2很好但我不知道这里的问题是什么

错误是一个无法匹配的预期类型[Char]与实际类型Char

提前谢谢

2 个答案:

答案 0 :(得分:7)

你根本不想要do符号,只是普通的变量绑定。所以:

func str = str2 where
    str1 = filter (<'a') str
    str2 = map digitToInt str1

跟踪最近使用的名称很烦人,不是吗?此外,它很容易出错,并在某处或类似地点击str而不是str1。输入功能组成:

func str = str2 where
    str2 = (map digitToInt . filter (<'a')) str

事实上,我会内联str2的定义,然后完全忽略str

func = map digitToInt . filter (<'a')

我希望isDigit优于(<'a');我们可以在同一时间投入一笔款项。

func = sum . map digitToInt . filter isDigit

在我看来,读起来很干净。

答案 1 :(得分:1)

可以使用do表示法,因为字符串是列表,列表是monad。但是看起来像这样:

func :: String -> [Int]
func str = do
  c <- filter (< 'a') str  -- Get one character
  return (digitToInt c)    -- Change that character to a integer

c的价值是多少?它不仅仅是一个角色,而是所有。列表monad模型非确定性。想象一下,func生成自己的多个副本,每个副本从输入字符串中选择不同的字符creturn从结果中创建一个新列表,monad负责将各个列表粘合到一个最终列表中。如果你将它与解构的形式进行比较,那就更清楚了。

func str = filter (< 'a') str >>= \c -> return (digitToInt c)

xs >>= f = concatMap f xs个实例中的return x = [x]Monad []后,它变为:

func str = concatMap (\c -> [digitToInt c]) (filter (< 'a') str)

但是,monadic形式不是必需的,因为你的函数只需要使用Functor的{​​{1}}实例,因为第一个列表中的每个元素都对应于最终名单:

[]