有什么方法可以为 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))
Run Code Online (Sandbox Code Playgroud)
当我在 haskell 中编译它时,出现类型错误“Int”与“String”不匹配。我想知道是否有任何方法可以将 lambda 函数“pow”l 的输入变量定义为语言。任何想法?
您可以使用ScopedTypeVariables语言扩展来启用此语法:
\(x :: Int) -> x
Run Code Online (Sandbox Code Playgroud)
-XScopedTypeVariables您可以在 GHC 命令行上启用扩展,或者通过输入
{-# LANGUAGE ScopedTypeVariables #-}
Run Code Online (Sandbox Code Playgroud)
在源文件的顶部。
正如我在对该问题的评论中指出的那样,这实际上可能无助于解决您的错误。对于许多简单的 Haskell 代码(包括您的代码),添加类型签名实际上不会对代码进行类型检查(否则不会进行类型检查)。它将做的是使定位类型错误变得更加容易,因为您会清楚您的意图和编译器推断的不同之处。
编辑以下评论中的讨论:
您的代码的问题在于您试图pow仅使用 lambda 定义递归函数,这是直接不可能的。您的 lambda需要一个函数pow作为参数,但您没有传递一个函数。
正如 @chi 的回答和评论所指出的,使用子句您的代码可能会最干净,但是如果您确实想保留内联 lambda,where您也可以这样做。fix
它具有以下类型和定义:
fix :: (a -> a) -> a
fix f = let x = f x in x
Run Code Online (Sandbox Code Playgroud)
在这种情况下,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))
Run Code Online (Sandbox Code Playgroud)
您可能需要将其添加到模块顶部的导入中:
import Data.Function (fix)
Run Code Online (Sandbox Code Playgroud)
您可以查看此问题以获取更多讨论fix。
| 归档时间: |
|
| 查看次数: |
364 次 |
| 最近记录: |