2013-09-29 59 views
0
ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float) 
    ver g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2))) 
    ver g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2))) 
    ver g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2))) 
    ():g++g1++g2 

我寫這篇文章,我不斷收到錯誤:赤裸裸的表達在頂級初學Haskell的

我想要做的是採取3樓與樓之間的距離,並呈現它們作爲爲例元組: (dAB,dBC,dAC)

回答

3

你的意思是

ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float) 
ver x y z = (g,g1,g2) where 
    g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2))) 
    g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2))) 
    g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2))) 

來編譯,並給出

> ver (1,1) (4,-3) (8,0) 
(5.0,7.071068,5.0) 
對作爲參數給出的三點之間的距離

...三(3元組)。

「裸體表達式」錯誤意味着你在一行不是函數的東西 - 你的最後一行。相反,我用where介紹你中間計算,但我也可以同樣使用了let ... in ...

ver' :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float) 
ver' x y z = let 
    g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2))) 
    g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2))) 
    g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2))) 
    in (g,g1,g2) 

記號():g++g1++g2看起來像你有元組和列表有點混亂。您可以從空列表中構建列表,但不能構建元組。

例如,你可以做1:3:8:[]這是一樣的[1,3,8],但你不能這樣做,因爲1:3:8:()()空的元組,而不是空的列表(類型錯誤),你不能這樣做,因爲[]:1:3:88不是一個清單,:需要一個清單的權利它。 (這意味着你可以如此迅速地快速添加到列表的前面,而不是後面。)

也許這是值得你通過教程的學習,回答所有練習 - 你似乎有一個Haskell編程的概念性圖片在實際的細節上很短。我可以推薦Learn You a Haskell for Great Good這是愉快地寫,可訪問,你可以免費在線閱讀。只記得實際上做所有的練習,並且測試你的答案工作! (使用ghci或擁抱。)通過定期測試和檢查,您將學得更快。

0

我相信你是單獨這樣希望的模式匹配的所有三元組作爲

type Location = (Float, Float) 
ver :: Location -> Location -> Location -> (Float, Float, Float) 
ver (aX, aY) (bX, bY) (cX, cY) = (0, 0, 0) {- Your logic -} 

這會給你訪問所有三個位置,IE的x,y元組。

作爲一種更好的處理方式,你可以重新思考你的函數來轉換一個位置數組,並返回一個距離數組。這將允許你寫更優雅的解決方案

0

問題是與最後一行:():g++g1++g2。那是裸露的表情。在文件的頂層,您只能定義像ver g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2)))或類型註釋,如ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float)。爲了擺脫分析錯誤,只需從文件中刪除最後一行。

但是,在您擺脫瞭解析錯誤之後,您將得到另一個有關ver類型的錯誤,與您在註釋中說的內容不匹配。如果您已經完成了明確的類型註釋,這是一個非常好的參數,因爲它清楚瞭解代碼是否存在誤解。在你的情況下,你認爲ver函數一次只能處理一行,這是不正確的。按照現狀,ver的類型應該是t -> Double。您可以通過註釋類型註釋來檢查它,使用ghci加載函數並輸入:t ver。這會給你Haskell看到的類型。

我認爲你前進的最簡單的方法是,如果我給你一個工作示例:

cityA = (3,4) 
cityB = (1,2) 
cityC = (6,3) 

dist :: (Double, Double) -> (Double, Double) -> Double 
dist city1 city2 = sqrt((fst city1 - fst city2)^2 + (snd city1 - snd city2)^2) 

tripleDist :: (Double, Double) -> (Double, Double) -> (Double, Double) -> (Double, Double, Double) 
tripleDist city1 city2 city3 = (d12, d13, d23) 
    where d12 = dist city1 city2 
      d13 = dist city1 city3 
      d23 = dist city2 city3 

dists = tripleDist cityA cityB cityC 

我希望這有助於。

1

在我開始列出你的代碼有什麼問題以及如何修復它之前,我建議先閱讀一些教程或者haskell introdutory文本,比如Learn You a Haskell for Great Good,因爲你的代碼顯示你沒有掌握一些基本的語法。

首先,你的錯誤來自

():g++g1++g2 

在Haskell中,無論是在top level(0壓痕)必須是(進口,類型簽名)某種形式的聲明的一部分或如何執行一個函數。所以你有一些東西的實現(雖然錯了,但稍後會更多),但問問自己,「我怎麼知道這行與Ver有關?」。那麼,在哈斯克爾你有特殊的關鍵字如letwhere來表達這一點。既然你沒有這些,那麼這行代碼就會丟失,而不是與實現有關,並且它不能存在於頂層 - 從而導致錯誤。我將展示如何儘快解決這個問題。

其次,該行不符合您的期望。 ()表示一個空元組,:是列表構造函數,++是列表附加。無論是做才能創造花車的元組感覺^ 3

你需要的東西如:

(,,) g g1 g2 
--or 
(g,g1,g2) 

三,你的功能實現是無關的什麼類型規定。也就是說,您有3個版本的ver來代替具有3個參數的ver。再問自己,「我怎麼知道x y z從哪裏來?」?

如果要定義一個函數有3個參數是這樣的函數應該什麼樣子:

ver x y z = -- Insert the calculations you want. 

看到了嗎? x y z是您的函數的輸入變量。無論你在= 的左側放置什麼都是輸入,無論來自右側,都是輸出。

好的,但g g1 g2怎麼樣?我怎麼能告訴我要計算這3個值,給他們一個名字,然後使用它們?

現在是時候使用我曾經告訴過你的where條款。看看你的函數應該什麼樣子:

ver :: (Float,Float)->(Float,Float)->(Float,Float)->(Float,Float,Float) 
ver x y z = (g,g1,g2) 
    where g=sqrt((((fst x -fst y)^2)+((snd x -snd y)^2))) 
      g1=sqrt((((fst x -fst z)^2)+((snd x -snd z)^2))) 
      g2=sqrt((((fst y -fst z)^2)+((snd y -snd z)^2))) 

而且一定要注意壓痕,因爲如果你把在那裏在同級別版本,你不表達,其功能在那裏屬於。