Haskell:使用 monad 链接函数时出错
Haskell : error while chaining function using monad
本练习的目的是获取一个字符串列表并构造一个字符列表,换句话说,给定下面的字符串列表
函数输入
let input = ["c", "cac", "cb", "bcc", "ba"]
应用一些行为
zip' xs = zip xs (tail xs)
let res1 =zip' input
将 (input) 列表中的每个元素与列表的其余部分压缩后,我将得到如下所示的元组列表
print res1
res1 = [("c","cac"),("cac","cb"),("cb","bcc"),("bcc","ba")]
在 res1 上应用一些其他行为
zip'' = \(a,b)->zip a b
let res2 = zip'' res1
压缩列表中每对的第一项和第二项将得到以下列表
print res2
res2 = [[('c','c')],[('c','c'),('a','b')],[('c','b'),('b','c')],[('b','b'),('c','a')]]
在 res2 上应用一些其他行为
let finalRes = concat res2
输出
print finalRes
finalRes= [('c','c'),('c','c'),('a','b'),('c','b'),('b','c'),('b','b'),('c','a')]
现在是单子风格
这个问题在没有 monad 的情况下很明显可以解决,虽然我是 monad 的新手并试图理解它,但我尝试使用绑定函数 >>=
来解决它,我写了 2 个函数和将它绑定在一起以便从 ** 输入 ** 到 输出 :
zip':: [String] -> [(String,String)]
zip' xs = zip xs (tail xs)
和
zip'' :: ([a], [b]) -> [(a, b)]
zip'' = \(a,b)->zip a b
然后
ff =zip'' >>= zip'
编译代码时,我在函数 ff 中遇到类型不对齐的错误。
让我重写绑定签名
Monad m => m a -> (a -> m b) -> m b
正在申请ff ["c", "cac", "cb", "bcc", "ba"]
据我所知,zip'
接受一个字符串列表,return 一个对列表,它是一个 context 对,所以它是绑定运算符的第一个参数 m a
,它应该与第二个函数 zip''
对齐。
因此函数 zip''
将采用每个 pair/tuple 并应用其行为以 return Char.
的串联列表
我错过了什么,代码中有什么问题?
抱歉问题太长了
你的 ff
功能倒退了。您应该从 zip'
开始并像这样绑定到 zip''
:
ff list = zip' list >>= zip''
运行 它通过 REPL 给你:
> let zip' xs = zip xs (tail xs)
> let zip'' = \(a,b)->zip a b
> let ff list = zip' list >>= zip''
> ff ["c", "cac", "cb", "bcc", "ba"]
[('c','c'),('c','c'),('a','b'),('c','b'),('b','c'),('b','b'),('c','a')]
本练习的目的是获取一个字符串列表并构造一个字符列表,换句话说,给定下面的字符串列表
函数输入
let input = ["c", "cac", "cb", "bcc", "ba"]
应用一些行为
zip' xs = zip xs (tail xs)
let res1 =zip' input
将 (input) 列表中的每个元素与列表的其余部分压缩后,我将得到如下所示的元组列表
print res1
res1 = [("c","cac"),("cac","cb"),("cb","bcc"),("bcc","ba")]
在 res1 上应用一些其他行为
zip'' = \(a,b)->zip a b
let res2 = zip'' res1
压缩列表中每对的第一项和第二项将得到以下列表
print res2
res2 = [[('c','c')],[('c','c'),('a','b')],[('c','b'),('b','c')],[('b','b'),('c','a')]]
在 res2 上应用一些其他行为
let finalRes = concat res2
输出
print finalRes
finalRes= [('c','c'),('c','c'),('a','b'),('c','b'),('b','c'),('b','b'),('c','a')]
现在是单子风格
这个问题在没有 monad 的情况下很明显可以解决,虽然我是 monad 的新手并试图理解它,但我尝试使用绑定函数 >>=
来解决它,我写了 2 个函数和将它绑定在一起以便从 ** 输入 ** 到 输出 :
zip':: [String] -> [(String,String)]
zip' xs = zip xs (tail xs)
和
zip'' :: ([a], [b]) -> [(a, b)]
zip'' = \(a,b)->zip a b
然后
ff =zip'' >>= zip'
编译代码时,我在函数 ff 中遇到类型不对齐的错误。
让我重写绑定签名
Monad m => m a -> (a -> m b) -> m b
正在申请ff ["c", "cac", "cb", "bcc", "ba"]
据我所知,zip'
接受一个字符串列表,return 一个对列表,它是一个 context 对,所以它是绑定运算符的第一个参数 m a
,它应该与第二个函数 zip''
对齐。
因此函数 zip''
将采用每个 pair/tuple 并应用其行为以 return Char.
我错过了什么,代码中有什么问题?
抱歉问题太长了
你的 ff
功能倒退了。您应该从 zip'
开始并像这样绑定到 zip''
:
ff list = zip' list >>= zip''
运行 它通过 REPL 给你:
> let zip' xs = zip xs (tail xs)
> let zip'' = \(a,b)->zip a b
> let ff list = zip' list >>= zip''
> ff ["c", "cac", "cb", "bcc", "ba"]
[('c','c'),('c','c'),('a','b'),('c','b'),('b','c'),('b','b'),('c','a')]