理解Haskell中为什么可能存在类型签名的困难
嗨,我很难理解我的函数需要的类型签名理解Haskell中为什么可能存在类型签名的困难,haskell,types,maybe,type-signature,Haskell,Types,Maybe,Type Signature,嗨,我很难理解我的函数需要的类型签名 -- findPassword :: Map.Map Hash Passwd -> Int -> Hash -> Maybe Passwd findPassword rTable width hashVal = do let usefulHashes = take (width+1) (iterate (pwHash.pwReduce) hashVal) let hashesInMap = [i | i <- usef
-- findPassword :: Map.Map Hash Passwd -> Int -> Hash -> Maybe Passwd
findPassword rTable width hashVal = do
let usefulHashes = take (width+1) (iterate (pwHash.pwReduce) hashVal)
let hashesInMap = [i | i <- usefulHashes, Map.member i rTable]
let goodPass = [ rTable Map.! j | j <- hashesInMap]
let findPass = listToMaybe [ helper k hashVal width | k <- goodPass, (helper k hashVal width) /= "" ]
return findPass
where
helper :: Passwd -> Hash -> Int -> Passwd
helper passW hashVal width
| (pwHash passW) == hashVal = passW
| width == 0 = ""
| otherwise = helper (pwReduce (pwHash passW)) hashVal (width-1)
所以我的问题是为什么它期望一个Maybe(Maybe Passwd)值?如果我将类型签名切换到Maybe(Maybe Passwd),它可以工作,但是输出应该是一个double,即“Passwd”。如果我删除类型签名,它就可以正常工作。这只是项目其余部分的一个小片段,如果需要澄清,请告诉我。Haskell不是Java。您不应该以
返回来结束一切。要让它工作,只需将returnfindpass
更改为findPass
。您还应该考虑删除冗余<代码> Do/<代码>块,只使用<代码> < < /C> >而不是所有的<代码> > <代码> S.< /P>请发布一个。这应该包括一个main
函数,该函数说明如何调用该findPassword
函数。我建议您了解何时应该使用do
,何时不应该使用。当一个函数只是在进行计算时,你不应该使用do
@code学徒这已经是一个最小的可重复的例子。问题是它的推断类型与签名中所需的类型不匹配,您只需要编译代码来复制它,而不是运行它。@JosephSible@Monica对于比我更了解Haskell的人来说,这里可能有足够的信息来给出合理的答案。但是,我无法重现OP()所声称的错误,因此我要求提供更多的细节,以便我可以自己玩它。@Code-pedurent啊,我明白了。OP忘记了导入,并在发布的代码中重命名了一个变量。所以这确实不是很容易复制,尽管原因与没有main
方法无关。这很有效,谢谢,你能解释一下为什么我不能在那里使用return语句吗?@cksss Haskell中没有return语句return
只是一个函数,没有理由期望对数据调用随机函数会有帮助。一般来说,不要依赖其他语言的经验来预测给定函数的功能,尤其是仅基于其名称。查看类型,并阅读文档以了解它的真正功能。@cksss(IMO)名称不好的return
函数获取一个值并将其包装在Monad
中。所以如果你给它一个也许Int
,它会吐出一个也许(也许Int)
或者一个[也许Int]
,或者一个IO(也许Int)
。在这种情况下,return
所能给出的任何值都不是函数返回的正确内容。现在,由于Monad
意味着Applicative
,我建议在必要时使用pure
(它将值包装在Applicative
中)而不是return
,因为语义更好。也就是说,这里既不需要pure
也不需要return
(实际上两者都不能使用)。
* Couldn't match type `Maybe Passwd' with `[Char]'
Expected type: Maybe Passwd
Actual type: Maybe (Maybe Passwd)
* In a stmt of a 'do' block: return result
In the expression:
do let usefulHashes
= take (width + 1) (iterate (pwHash . pwReduce) hashVal)
let hashesInMap = ...
let goodPass = ...
let findPass = ...
....
In an equation for `findPassword':
findPassword rTable width hashVal
= do let usefulHashes = ...
let hashesInMap = ...
let goodPass = ...
....
where
turntoMaybe :: [Passwd] -> Maybe Passwd
turntoMaybe list = listToMaybe list
helper :: Passwd -> Hash -> Int -> Passwd
helper passW hashVal width
| (pwHash passW) == hashVal = passW
| width == 0 = ""
| otherwise = helper (pwReduce (pwHash passW)) hashVal (width - 1)
|
78 | return result