我试图找出是否有可能在Haskell集合理解中模式匹配.我有一个包含元组或嵌套列表和元组的列表列表;
例如
[[(1,("A",1)), (2,("B",1))], [(0,("A",1)), (3,("B",2)), (2,("C",1))]]
Run Code Online (Sandbox Code Playgroud)
我想丢弃包含"A"的元组,并在其他元素上执行任意计算.
我在思考:
pack(xs:xss) = [package x | x <- xs, x /= (1,("A", 1))] : (pack xss)
pack(_) = []
package x = case x of
(i, ("B", j)) -> (i + j, ("B", j * i))
(i, ("C", j)) -> (i * j, ("C", j + i))
(otherwise) -> x
Run Code Online (Sandbox Code Playgroud)
以下可能允许使用通配符:
x /= (1,("A", 1))
Run Code Online (Sandbox Code Playgroud)
如:
x /= (_,("A", _))
Run Code Online (Sandbox Code Playgroud)
值得注意的是,嵌套元组中的数字将始终为int类型,不确定是否有帮助......
我环顾四周但看不出这是否可能,似乎过滤是一个更好的选择,如下所述; 但是我们正在过滤未知数.
我的问题是来自更大的工作/功能的抽象示例,但希望我已经在这里捕获了问题的本质.我愿意接受其他建议.
谁能告诉我如何一次搜索整个阵列中的模式,例如
@array = ('I am AA','I am BB', 'I am CC', 'I am AAC')
$pattern = "AA"
Run Code Online (Sandbox Code Playgroud)
我使用以下逻辑但它不起作用
if (@array =~ /$pattern/) {
# do this;
} else {
# do that
}
Run Code Online (Sandbox Code Playgroud)
谢谢
请考虑以下数据定义:
data Foo = A{field::Int}
| B{field::Int}
| C
| D
Run Code Online (Sandbox Code Playgroud)
现在让我们假设我们想编写一个函数,如果它存在则需要Foo增加并增加field,否则保持不变:
incFoo :: Foo -> Foo
incFoo A{field=n} = A{field=n+1}
incFoo B{field=n} = B{field=n+1}
incFoo x = x
Run Code Online (Sandbox Code Playgroud)
这种天真的方法会导致一些代码重复.但是这两个A和B共享field允许我们重写它的事实:
incFoo :: Foo -> Foo
incFoo x | hasField x, n <- field x = x{field=n+1}
incFoo x = x
hasField A{} = True
hasField B{} = True
hasField _ = False
Run Code Online (Sandbox Code Playgroud)
不那么优雅,但是当实际操作很复杂时,它更容易维护.这里的关键特征是x{field=n+1}- 记录语法允许我们"更新" field而不指定x类型.考虑到这一点,我期望类似于以下语法(不支持): …
我在haskell中有以下两个函数:
plusList :: [[Int]] -> [Int]
plusList [xs ys] = add xs + plusList [ys]
plusList [[]] = 0
add::[Int] -> Int
add (x:xs) = x + add xs
add [] = 0
Run Code Online (Sandbox Code Playgroud)
所以,我认为我在plusList [xs ys] =添加xs + plusList ys中有错误
我的想法是通过设置集合,即[[Int]],通过取第一个List xs,在其上应用"add",然后用"plusList ys"递归调用第二个列表ys
我是哈斯克尔的新手,我可以这样做吗?如果不是,为什么?
在下面的代码中,Haskell抱怨
Non-exhaustive patterns in function prime'
prime :: Int -> [Int]
prime x = prime' [2..x] where
prime' (p:ps)= p : prime' [x | x <- ps, mod x p > 0 && prime'' x [2..div x 2]]
prime'' _ [] = True
prime'' n (x:xs)
| mod n x == 0 = False
| otherwise = prime'' n xs
prime' []=[]
Run Code Online (Sandbox Code Playgroud)
我找不到我的错误.有人可以解释为什么会发生这种情况,这意味着什么?
假设我有下表(称为文件表),文件名为:
file
something.h
something.cc
somethingelse.js
something.py
something.xkh
something.jpeg
Run Code Online (Sandbox Code Playgroud)
我尝试了以下查询:
select file
from filetable
where file ~ E'\.[cc|h|js|py]';
Run Code Online (Sandbox Code Playgroud)
查询输出是:
file
something.h
something.cc
somethingelse.js
something.py
something.xkh
something.jpeg
Run Code Online (Sandbox Code Playgroud)
但是,我只需要完全使用.cc,.h,.js,.py完成的文件.如何改进此查询?
我有一个评估函数(expr_eval/1),它应该评估一个表达式并返回一个数字.到目前为止,我的函数返回有效数字,如:
expr_eval({plus,{num, 17},{num,10}}) ? 27
Run Code Online (Sandbox Code Playgroud)
但不是这个:
expr_eval({mul,{plus,{num,5},{num,8}},{num,3}}) ? 39
Run Code Online (Sandbox Code Playgroud)
我的职责:
expr_eval({mul, {num,A}, {num,B}}) ->A*B;
expr_eval({plus, {num,A}, {num,B}}) ->A+B;
expr_eval({minus, {num,A},{num,B}}) ->A-B;
expr_eval({_,_,_})->nothing_matched.
Run Code Online (Sandbox Code Playgroud)
我知道它只是按原样采用模式,但我该如何解决这个问题呢?我可以硬编码并将下面的代码添加到我的函数中,上面的方程式可以正常工作,但它不适用于其他方程式.(例如expr_eval({minus,{plus,{num,5},{num,8} },{num,3}})→8)
expr_eval({mul, {plus,{num,A},{num,B}},{num,C}}) ->(A+B)*C;
Run Code Online (Sandbox Code Playgroud) 我正在使用System.FilePath.Findfilemanip模块以递归方式查找我需要处理的所有文件(这里我将仅使用打印到控制台作为要执行的操作,以免混淆事物).现在,这段代码:
import System.Environment (getArgs)
import System.FilePath (FilePath)
import System.Directory (doesDirectoryExist, getDirectoryContents,doesFileExist)
import Control.Monad
import System.FilePath.Find (find,always,fileType,(==?),FileType(..),(&&?),extension)
main= do
[dbFile,input]<- getArgs
files <- findFiles input
mapM_ putStrLn files
return ()
searchExtension :: String
searchExtension = ".hs"
findFiles :: FilePath -> IO [String]
findFiles = find (always) ( fileType ==? RegularFile &&? extension ==? searchExtension)
Run Code Online (Sandbox Code Playgroud)
适合这个电话
./myprog tet.
在这种情况下,将get忽略该参数(稍后将是输出数据库文件),并且为匹配文件递归搜索第二个参数.它还允许我只指定一个文件,这是完美的!
但是,我希望能够指明
./myprog tet path1 path2 path4 file1
但这当然在模式匹配中失败了:
./myprog tet..
myprogt:用户错误(myprog.hs中的do表达式中的模式匹配失败:11:9-22)
现在,我如何使这个程序更灵活,以便我可以采取两个以上的参数?
很抱歉这个问题,但是我的Haskell知识是有限的,但是在我的第一个项目中我必须做的每件新事情都在增加.
我有一个模式匹配的元组,并以递归方式对每个元素执行一些操作.
[(Int, Char, Int)]
Run Code Online (Sandbox Code Playgroud)
我找到了如何正确模式匹配它来访问每个元素,如下所示:
((q1, s, q2):tss)
Run Code Online (Sandbox Code Playgroud)
有了这个,我可以对列表中的每个元素进行一些检查操作.我打算如何递归地对元组中的其余元素执行相同的操作,在本例中是tss.
这是我在这里发布的代码的一部分:
case ts of
[] -> False
((q1, s, q2):tss) | not (q1 `elem` qs) -> False
| not (s `elem` qs) -> False
| not (q2 `elem` qs) -> False
Run Code Online (Sandbox Code Playgroud)
我应该如何递归地对tss进行相同的测试?想法将不胜感激.
我是Haskell编程语言的新手,我正在尝试创建一个数据类型来表示二进制数,并编写一个函数来计算其十进制值.
我想用二进制数字代表这个BNF
Numeral ::= 0 | 1 | Numeral 0 | Numeral 1
我使用模式匹配和像这样的字段标签在haskell中构建了它的数据类型
data Numeral = Zero | One | Num {number :: Numeral, suffex :: Int}
我创建了一个函数
valuate Zero = 0
valuate One = 1
valuate Num(n:0) = 2 * valuate (n)
valuate Num(n:1) = 2 * valuate (n) + 1
valuate Num(n:ns) = error "Not binary number"
Run Code Online (Sandbox Code Playgroud)
但我得到一个编译错误"'估计'的例外'有不同数量的参数"
我试图理解我所犯的错误在哪里,我将Numeral传递给具有不同构造值的每个模式中的方法,甚至在我调用时(2*评估n)我传递的是"n",这是构造中的Numberal'民"
我的数据类型或函数模式中的问题是什么?
pattern-matching ×10
haskell ×7
erlang ×1
filtering ×1
io-monad ×1
list ×1
parse-error ×1
perl ×1
postgresql ×1
recursion ×1
regex ×1