haskell中的怪异类型问题给我问题(Par Monad)

haskell中的怪异类型问题给我问题(Par Monad),haskell,types,Haskell,Types,参考我的代码 import Control.Monad.Par makeGridx:: (Enum a,Num a)=>a->a->a->[a] makeGridx start end h = [start,(start+h)..end] makeGridt:: (Enum a, Num a)=>a->a->a->[a] makeGridt start end h = [start,(start+h)..end] generateBaseLin

参考我的代码

import Control.Monad.Par

makeGridx:: (Enum a,Num a)=>a->a->a->[a]
makeGridx start end h = [start,(start+h)..end]
makeGridt:: (Enum a, Num a)=>a->a->a->[a]
makeGridt start end h = [start,(start+h)..end]

generateBaseLine:: (Eq a,Num a)=>(a->a)-> [a] -> [(a,a,a)]
generateBaseLine f (x:xs) = if (null xs)
                            then [(x,0,0)]
                            else if(x==0)
                                then (x,0,0) : (generateBaseLine f xs)
                                else (x,0,(f x)) : (generateBaseLine f xs)

--fdm :: (Enum a,Num a) =>a->a->a->a->a->a->a->(a->a)->[(a,a,a)]
--fdm alpha startt endt startx endx dx dt bbFunction = start alpha (makeGridx startx endx dx) (makeGridt startt endt dt) (generateBaseLine bbFunction (makeGridx startx endx dx)) dx dt

--start:: Num a=>a->[a]->[a]->[(a,a,a)]->a->a->[(a,a,a)]
--start alpha (x:xs) (t:ts) (phi:phis) dx dt =  (startPar alpha (x:xs) (ts) (phi:phis) dx dt [] [])

startPar:: Num a =>a->[a]->[a]->[(a,a,a)]->a->a->[(a,a,a)]
startPar alpha (x:xs) (t:ts) (phi1:(ph2:(ph3:phis))) dx dt = (phi1:(ph2:(ph3:phis))) ++ (buildPhiListIds alpha (x:xs) (t:ts) (phi1:(ph2:(ph3:phis))) dx dt [] [])
buildPhiListIds:: Num a=> a->[a]->[a]->[(a,a,a)]->a->a->[Par (IVar (a, a, a))]->[a]->[(a,a,a)]                                                              
buildPhiListIds alpha (x:xs) (t:ts) (phi1:(ph2:(ph3:phis))) dx dt phiIds newX = do 
                                                                        one<-third phi1
                                                                        two<-third ph2
                                                                        three<-third ph3
                                                                        newSolId<- spawn( return (newPhi (x:xs) t (one,two,three,dx,dt,alpha) ))
                                                                        buildPhiListIds alpha xs (t:ts) (ph2:(ph3:phis)) dx dt (phiIds ++ [newSolId]) (newX ++ [x])

buildPhiListIds alpha (0:xs) (t:ts) (phi1:(ph2:(ph3:phis))) dx dt phiIds newX = do 
                                                                        newSolId<-spawn (return (newPhi (0:xs) t (1,2,3,4,5,6)))            
                                                                        buildPhiListIds alpha xs (t:ts) (phi1:(ph2:(ph3:phis))) dx dt (phiIds ++ [newSolId]) (newX ++ [0])

buildPhiListIds alpha [] (t:ts) (phi1:(ph2:(ph3:phis))) dx dt phiIds newX = do
                                                                            (getSolutions (getTuples(getSolutions phiIds))) ++ (buildPhiListIds alpha newX  ts (getSolutions (getTuples(getSolutions phiIds)))  dx dt [] []) 

buildPhiListIds _ _ [] _ _ _ _ _ = []


getTuples::[IVar a]->[Par a]
getTuples (x:xs) = (get x) : (getSolutions xs)
getTuples [] = []  

getSolutions:: [Par a]->[a]
getSolutions (x:xs) = (runPar x):(getTuples xs)
getSolutions [] = []


third (_,_,x)=x

ex f g x = runPar $ do
      fx <- spawn (return (f x))  
      gx <- spawn (return (g x))  
      a <- get fx       
      b <- get gx       
      return (a,b)      
newPhi:: (Eq a,Fractional a)=> [a]->a->(a,a,a,a,a,a)->(a,a,a)
newPhi (0:xs) t (phiL,phiC,phiR,dx,dt,alpha)= (0,t,0)
newPhi (x:[]) t (phiL,phiC,phiR,dx,dt,alpha)= (x,t,0)
newPhi (x:xs) t (phiL,phiC,phiR,dx,dt,alpha)= (x,t,(phiC + (alpha * (dt/(dx^2)))*(phiR -(2*phiC) + phiL)))
我没有看到具体类型的[IVar(a1,a1,a1)],这让我很困惑。如果有人能引导我走上正确的道路,我将不胜感激

我犯了很多错误,但有一个让我很复杂

do
表达式中,每个一元动作必须属于同一个一元。
buildalistids
的返回类型是
[something]
,因此
do
的结果具有类型
[something]
。因此,你的所有动作应该在列表单元格中,而不是在单元格中。现在再次查看
spawn

spawn :: NFData a => Par a -> Par (IVar a)
将我上面提到的内容与您的错误进行比较:“无法将'Par'类型与'[]'匹配”。啊哈!它需要一个列表,但是你使用了错误的类型(
Par

现在,从你的理论推断,我想你对哈斯克尔和单子的概念是陌生的。有很多关于它们的内容,包括章节,所以我不会在这个答案中提供(它们实际上相当简单,不要被教程的数量吓倒)。无论哪种方式,您当前的使用都完全停止

也就是说,您应该重构
buildalistids
,使其具有以下类型:

buildPhiListIds:: Num a => ... -> Par [(a,a,a)]
此外,您对
getTuples
getSolutions
的定义没有多大意义。以下内容简单得多,可能实现了您的实际需求:

getTuples :: [IVar a] -> [Par a]
getTuples = map get

getSolutions :: [Par a] -> [a]
getSolutions = runPar . sequence 
此外,您应该尽量减少对
runPar
的调用:

runPar
函数本身相对昂贵[…]。因此,当使用
Par
monad时,通常应该尝试将
Par
monad线程化到所有需要并行性的地方,以避免需要多次
runPar
调用。特别是,嵌套调用到“代码> RunPA4/CODE >(其中在执行另一个PAR计算的过程中评估<代码> RunPAR/代码>)通常给出较差的结果。
我建议您编写一些更简单的程序来实际编译,直到您得到一般的monad和
Par

它似乎
spawn
返回
Par
而不是
[]
。替换
为什么它期望[IVar(a,a,a)]?@特征值:让我重新表述这个问题:为什么它期望
[]
而不是
Par
作为外部数据类型?提示:这已经包含在我的答案中了。另外,我怀疑你没有阅读任何关于单子的附加信息,因为这会让事情变得更清楚。
buildPhiListIds:: Num a => ... -> Par [(a,a,a)]
getTuples :: [IVar a] -> [Par a]
getTuples = map get

getSolutions :: [Par a] -> [a]
getSolutions = runPar . sequence