2015-03-30 16 views
9

我是Haskell的新手,我嘗試應用一個函數(gcd)輸入標準輸入,它是行分隔的,每行包含不少於或多於兩個數字。這是我輸入的例子:Haskell - 嘗試將函數應用於多個數字的行

 
3 
10 4 
1 100 
288 240 

我目前分手每一行到這兩個數字的元組,但我有麻煩找出如何分離這些元組和應用功能給他們。以下是我迄今爲止:

import Data.List 

main :: IO() 
main = do 
    n <- readLn :: IO Int 
    content <- getContents 
    let 
    points = map (\[x, y] -> (x, y)). map (map (read::String->Int)). map words. lines $ content 
    ans = gcd (fst points :: Int) (snd points :: Int) 
    print ans 

兩個一個好地方,開始尋找這個答案的任何信息,將不勝感激。我已閱讀了學習Haskell教程,並沒有找到有關此特定問題的任何信息。

+1

試着寫一個純函數'˚F::字符串 - > Int',這需要你的線路輸入和計算gcd第一。在第二步中將該函數應用於'main'內的輸入。還可以看看Prelude的'uncurry ::(a - > b - > c) - >((a,b) - > c)'。 – sjakobi 2015-03-30 23:36:19

回答

3

你很親密。在調用gcd之前,沒有理由將其轉換爲元組或元組列表。

main = do 
    contents <- getContents 
    print $ map ((\[x,y] -> gcd (read x) (read y)) . words) . lines $ contents 

所有有趣的事情是printcontents之間。 lines將把內容分成幾行。 map (...)將函數應用於每一行。 words將行分割成單詞。 \[x,y] -> gcd (read x) (read y)將在兩個字符串的列表上匹配(並且拋出一個錯誤,否則拋出一個錯誤 - 通常不是很好的做法,但對於像這樣的簡單程序很好),將這些字符串讀作Integer s並計算它們的GCD。

如果要使用惰性IO,爲了在輸入每行後打印每個結果,可以按如下方式進行更改。

main = do 
    contents <- getContents 
    mapM_ (print . (\[x,y] -> gcd (read x) (read y)) . words) . lines $ contents 
+0

您需要跳過僅包含單個結果條目數的第一行。 – Yuuri 2015-03-31 10:40:19

+0

謝謝大家的快速回復。我現在看到了這一切到底是怎麼回事,我也必須在前奏中看清楚。 – midnightconman 2015-03-31 18:42:46

0

或者,你可以做一個更爲迫切的風格:

import Control.Monad 

main = do 
    n <- readLn 
    replicateM_ n $ do 
     [x, y] <- (map read . words) `liftM` getLine 
     print $ gcd x y 
相關問題