2014-11-17 3 views
-1

Это программа, которую я написал для добавления списка элементов, которые могут содержать как float, так и целое число. Кажется, что не работает вообще, и мой лектор так же бессовестен в этом, как и я, и я не могу найти подходящее решение для этого, попробовал перечислить список, однако большинство примеров используют прямые входы в программы GHC not IO(). Также пытается использовать HOF (функции более высокого порядка), как видно из функции «summ».Добавление элементов списка списка в haskell (не конкатенация, но добавление)

conc :: Num a => [[a]] -> [a] 
    conc [] = [] 
    conc xss = [x | xs <- xss , x <- xs] 

    summ :: ([[a]] -> [a]) -> [[a]] ->[a] 
    summ [[f]] [[s]] = f (s) 
    summ (h : t) = h + summ t 

    summer :: IO() 

    summer = do 
       putStr "Enter a List of List (Int/Float): " 
       li <- getLine 
       let li = (read li) :: [[Float]] 

       let r = summ (conc li) 

       putStrLn "Sum of the list of lists is: " ++ r 
+0

Ваша функция 'summ' принимает разные количества аргументов, и в первом случае, по-видимому, требуется список списков функций и список списков значений? Напротив, строка типа ссылается на одну функцию (список списков значений) и список списков значений. Из-за несоответствий в определениях, похоже, вы пытаетесь заставить его делать сразу две совершенно разные вещи –

ответ

1

Так я решил мой собственный вопрос для тех, кто застрял с той же проблемой здесь является решением.

conc::[[Int]]->[Int] -- taking a list-of-list as an argument and returning only a list. 
conc [] = [] -- base case 
conc (h:t) = h ++ conc t -- written to concatenate the list of lists. 


summ::[Int]->Int 
summ[]=0 
summ (h:t) = h + summ t -- to sum up the elements of the list of list 

summer1::([Int]->Int)->([[Int]]->[Int])->[[Int]]->Int -- A higher order function 
summer1 a b l = summ(conc l)       

summer::IO() 
summer = do 
      putStr "Enter a list of list of integers: " 
      x <- getLine 
      let y = (read x) :: [[Int]] 

      let sol = summer1 summ conc (y) -- takes the HOF and then applies to y 
      putStrLn ("The sum of the elements of the list of list is: " ++ show sol) --displaying the result 
1

Вы можете попробовать

conc = map sum 

, чтобы получить подпись Num a => [[a]] -> [a], что вы ищете с (+) операции между элементами.

Кроме того, у summ есть подпись ужасного типа и предоставит вам все возможные ошибки. Вы, вероятно, просто означали sum, так как вы называете это на выходе conc.

Так, например, это «просто работает»:

main = do 
    putStrLn "Enter a list of lists of floats: " 
    floats <- readLn :: IO [[Float]] 
    putStrLn $ "Sum of the list of lists is: " ++ show (sum $ map sum $ floats) 

(Здесь a $ b = a b, то $ знак является функцией, которая помогает устранить круглые скобки, будучи очень низким старшинства и правоассоциативной, он в основном говорит на пример «putStrLn остальной части этого выражения».)

1

Ваша функция summ очень не правильная. Во-первых, вы не укажете все аргументы summ во второй строке своего определения, но настоящая проблема исходит из сопоставления шаблонов в summ [[f]] [[s]]. Вы сказали компилятору, что summ имеет тип ([[a]] -> [a]) -> [[a]] -> [a], что означает, что первый аргумент для summ должен быть функцией, но шаблон [[f]] - это список, содержащий список, содержащий один элемент под названием f. Это справедливо и для шаблона [[s]], который не соответствует ни одному списку, только такой список, как [[1]] или [[10]], он не соответствует [], [[1, 2, 3]], [[1],[2],[]] или любому другому значению для вложенного списка. Если вы должны были изменить это

summ f s = f s 

Тогда эта функция не будет ничего более id для функций. Вместо этого, если вы хотите, чтобы получить сумму каждого списка внутри списка, вы могли бы просто использовать

summ l = map sum l 

Если вы хотите, вместо того, чтобы объединить список списков чисел в только список номеров, вы должны использовать встроенный concat функция.

В summer, у вас также есть summ (conc li), что было бы неправильно для функций высшего порядка, вместо него вы должны иметь summ conc li, где conc и li являются оба аргумента в summ. Однако я не думаю, что вам это нужно вообще. Наконец, в

putStrLn "Sum of the list of lists is: " ++ r 

не компилируется по 2 причинам: 1. это обрабатывается компилятором, как

(putStrLn "Sum of the list of lists is: ") ++ r 

и 2.вы не можете объединить значение на IO(). Если вы использовали круглые скобки правильно, как

putStrLn ("Sum of the list of lists is: " ++ r) 

это не будет работать, потому что ++ требует оба значения, чтобы быть того же типа, то есть вы можете только сцепить в String с другим String. Для преобразования значения String, вы можете использовать функцию show, так что это будет выглядеть

putStrLn ("Sum of the list of lists is: " ++ show r) 
Смежные вопросы