簡體   English   中英

Haskell中的奇怪類型問題給了我問題(Par Monad)

[英]weird type issue in haskell giving me issues (Par Monad)

供參考我的代碼。

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)))

我遇到了很多錯誤,但是卻使我非常復雜。

heateqpar.hs:28:156:
    Couldn't match type `Par' with `[]'
    Expected type: [IVar (a1, a1, a1)]
      Actual type: Par (IVar (a1, a1, a1))
    In a stmt of a 'do' block:
      newSolId <- spawn
                    (return (newPhi (x : xs) t (one, two, three, dx, dt, alpha))) ::
                    Par (IVar (a, a, a))
    In the expression:
      do { one <- third phi1;
           two <- third ph2;
           three <- third ph3;
           newSolId <- spawn
                         (return (newPhi (x : xs) t (one, two, three, dx, dt, alpha))) ::
                         Par (IVar (a, a, a));
           .... }
    In an equation for `buildPhiListIds':
        buildPhiListIds
          alpha
          (x : xs)
          (t : ts)
          (phi1 : (ph2 : (ph3 : phis)))
          dx
          dt
          phiIds
          newX
          = do { one <- third phi1;
                 two <- third ph2;
                 three <- third ph3;
                 .... }

這是我想要的實際類型,但由於某種原因,它試圖強制執行這種類型,而不是spawn的返回類型? 當我看到此內容時,似乎在我的類型聲明中嘗試執行此操作,但是我的類型如下

buildPhiListIds:: Num a=> a->[a]->[a]->[(a,a,a)]->a->a->[Par (IVar (a, a, a))]->[a]->[(a,a,a)]  

我沒有看到[IVar(a1,a1,a1)]的具體類型,這確實讓我感到困惑。 如果有人可以帶領我走上正確的道路,將不勝感激。

我遇到了很多錯誤,但是卻使我非常復雜。

do表達式中,每個單子動作必須屬於同一單子。 buildPhiListIds的返回類型為[something] ,因此do的結果為[something]類型。 因此,您的所有操作都應在列表 monad中,而不是在par monad中。 現在再次查看spawn

spawn :: NFData a => Par a -> Par (IVar a)

將我上面提到的錯誤與您的錯誤進行比較:“無法將類型“ Par”與“ []”匹配”。 啊哈! 需要一個列表 ,但是您使用的是錯誤的類型( Par )!

現在,從以前的問題中推斷出,我想您是Haskell和monad概念的新手。 有很多教程關於他們,包括章節在RWH在LYAH ,所以我不會提供一個在這個答案(它們實際上是相當容易的,不要被輔導的數字嚇倒)。 無論哪種方式,您當前的使用情況都將完全關閉。

話雖如此,您應該將buildPhiListIds重構為以下類型:

buildPhiListIds:: Num a => ... -> Par [(a,a,a)]

另外,您對getTuplesgetSolutions定義沒有多大意義。 以下內容要簡單得多,並且可能會實現您實際想要的功能:

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

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

另外,您應該盡量減少對runPar的調用:

runPar函數本身是相對昂貴的。 因此,在使用Par monad時,通常應嘗試將Par monad線程到所有需要並行處理的位置,以避免需要多次runPar調用。 [...]特別是,對runPar嵌套調用(在執行另一個Par計算的過程中對runPar進行評估)通常會產生較差的結果。

我建議您編寫一些實際上可以編譯的簡單程序,直到獲得一般的monad和Par為止。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM