有没有办法为lambda函数定义输入变量的类型。我已将此作为一项功能
bstar :: Language -> Int -> Language
bstar l n =
case l of
[] -> zero
l -> case n of
0 -> [[]]
n -> (\pow l n -> if n == 0
then [[]]
else l `cat` (pow l (n-1))) l n `uni` (bstar l (n-1))
当我在haskell中编译它时,我得到了不匹配类型错误' Int'用' String'。我想知道是否有任何方法可以定义lambda函数的输入变量" pow"作为一种语言。 有什么想法吗?
答案 0 :(得分:4)
您可以使用ScopedTypeVariables
语言扩展名来启用此语法:
\(x :: Int) -> x
您可以在GHC命令行上使用-XScopedTypeVariables
或通过
{-# LANGUAGE ScopedTypeVariables #-}
位于源文件的顶部。
正如我在对该问题的评论中所指出的,这实际上可能无法帮助您修复错误。对于很多简单的Haskell代码(包括你的代码),添加类型签名实际上并不会使代码类型检查得不到。它将会更容易找到类型错误,因为它会让你清楚你的意图和推断的编译器的不同之处。
在评论中讨论后编辑:
您的代码的问题在于您尝试使用lambda来定义递归函数pow
,这不是直接可能的。你的lambda 期望一个函数pow
作为参数,但你没有传递一个。
正如@ chi的回答和评论说明,您的代码可能会更简洁,而where
子句代替,但如果您真的想保留内联lambda,也可以使用fix
执行此操作。< / p>
它具有以下类型和定义:
fix :: (a -> a) -> a
fix f = let x = f x in x
在这种情况下,a
类型将是pow
函数的所需类型,即(Language -> Int -> Language)
。因此,fix
最终会将您的lambda变为递归定义 - x
定义中fix
对应于您的pow
。
bstar :: Language -> Int -> Language
bstar l n =
case l of
[] -> zero
l -> case n of
0 -> [[]]
n -> fix (\pow l n ->
if n == 0
then [[]]
else l `cat` (pow l (n-1))) l n `uni` (bstar l (n-1))
您可能需要将此添加到模块顶部的导入中:
import Data.Function (fix)
有关fix
的更多讨论,请查看this question。
答案 1 :(得分:4)
可能你正在寻找这样的东西:
bstar :: Language -> Int -> Language
bstar l n =
case l of
[] -> zero
l -> case n of
0 -> [[]]
n -> pow l n `uni` bstar l (n-1)
where pow :: Language -> Int -> Language
pow l n = if n == 0
then [[]]
else l `cat` pow l (n-1)
让我&#34; restyle&#34;一点你的代码,希望能让它更清晰。
bstar :: Language -> Int -> Language
bstar [] _ = zero
bstar _ 0 = [[]]
bstar l n = pow l n `uni` bstar l (n-1)
where pow :: Language -> Int -> Language
pow _ 0 = [[]]
pow l n = l `cat` pow l (n-1)