LINUX.ORG.RU

Haskell изменение типа

 


0

2

У меня такой вопрос, сначала был список списков типа [(Integer, [[Complex Double]], Double)] затем, мне необходимо было сделать действия над этим списком списков и я это сделала через main и на выходе у меня тип списка IO (), но структура этого списка сохранилась, я могу как-то опять изменить этот результирующий список на тип [(Integer, [[Complex Double]], Double)]?

Как-то смутно понятно. Что значит «сделала через main»? Можешь код показать?

Если есть переменная типа IO [(Integer, [[Complex Double]], Double)], то из неё можно получить [(Integer, [[Complex Double]], Double)] внутри main через

main = do
  ...
  x <- IO_x
  ...
monk ★★★★★ ()
Ответ на: комментарий от monk
task cs = map (\ q -> filter (\ (_,_,x) -> x==q) cs) xs
          where xs = nub $ map (\(_,_,x) -> x) cs
 
main = print $  task cs

a = [x | (_,x,_) <- main]

и тут возникает конфликт типов

Couldn't match expected type ‘[(a2, a, c0)]’
                  with actual type ‘IO ()’

list1-это список вида

[ [( 4, [[0.3 :+ 0.0], [0.0 :+ 0.0]], 0.0) , (5, [[0.2 :+ (-0.3)] ,[0.5 :+ 0.7]], 0.0)], [( 8 ,[[0.6 :+ 0.1],[0.1 :+ (-0.3)]]...
simona ()
Ответ на: комментарий от simona

Что ты пытаешься сделать?

В любом случае, полезно выписывать все типы явно, станет понятно, почему ничего не работает (если ты сначала прочитаешь learnyouahaskell.com, то будет вообще зашибись)

balsoft ★★ ()
Ответ на: комментарий от balsoft

task cs- берет список list1 (правильнее было написать cs) сортирует его по отношению последнего элемента, эта часть нормально работает.

Я получаю свой список

[ [( 4, [[0.3 :+ 0.0], [0.0 :+ 0.0]], 0.0) , (5, [[0.2 :+ (-0.3)] ,[0.5 :+ 0.7]], 0.0)], [( 8 ,[[0.6 :+ 0.1],[0.1 :+ (-0.3)]]...

типа:

:type (main)
(main) :: IO ()

И затем из этого результирующего списка мне надо взять только средний элемент (т.е. эти комплексные числа) и создать новый список

из примера выше, результат нужен такой

[ [[0.3 :+ 0.0], [0.0 :+ 0.0]] , [[0.2 :+ (-0.3)] ,[0.5 :+ 0.7]], 0.0)], [[0.6 :+ 0.1],[0.1 :+ (-0.3)]]...
simona ()
Ответ на: комментарий от simona

Ты вообще понимаешь, что main - это просто переменная, в которой лежит (будет лежать при вызове) пустое значение () упакованное в «тип» IO?

Сходи в irc, например, там тебе всё объяснят. Пока, судя по предыдущим темам, ты не понимаешь что вообще делаешь! Почитай learn you a haskell или иные книжки.

Серьёзно, сядь и попытайся осознать текст понравившегося туториала, а не херачить по рецептам, которые не понимаешь.

Ты создал(а) слишком много однотипных тем с элементарными вопросами. В интернете нельзя легко различить некомпетентность и злонамеренность, т.е. тупняк и троллинг. Но в обоих случаях это повод попросить изменить поведение. Пожалуйста, измени его!

anonymous ()
Ответ на: комментарий от simona

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

task cs = map (\ q -> filter (\ (_,_,x) -> x==q) cs) xs
          where xs = nub $ map (\(_,_,x) -> x) cs

task_cs_result = task cs

main = print $  task_cs_result

a = [x | (_,x,_) <- task_cs_result]

Не ясно что ты хочешь потом сделать с a, если нигде ее не вызываешь.

vertexua ★★★★☆ ()
Ответ на: комментарий от simona

Я так понимаю, ты хочешь вывести значение task cs, а потом продолжить вычисления с этим значением.

task cs = map (\ q -> filter (\ (_,_,x) -> x==q) cs) xs
          where xs = nub $ map (\(_,_,x) -> x) cs
main = do
    let ts = task cs
    print ts
    let a = [x | (_, x, _) <- ts]
    -- и так далее

Расставляй аннотации типов, так будет проще читать сообщения об ошибках.

Siborgium ()
Ответ на: комментарий от Siborgium

Ошибка возникает именно с выводом списка a, на это ругается.

task cs = map (\ q -> filter (\ (_,_,x) -> x==q) cs) xs
          where xs = nub $ map (\(_,_,x) -> x) cs
 
ts = task cs

a = [x | (_,x,_) <- ts]

и когда пытаюсь в WinGHci вызвать список а, то он ругается

Couldn't match expected type ‘[(Integer, [[Complex Double]],
                                      Double)]’
                  with actual type ‘(a0, a, c0)’


simona ()
Ответ на: комментарий от simona

С помощью a = [x | (_, x, _) <- ts] ты пытаешься вытащить вторые элементы всех триплетов? Это проще сделать с помощью

a = map (\(_, x, _) -> x) ts

если тебе важно починить имеющийся код, то расставляй типы, показывай минимально работающий пример.

Siborgium ()
Ответ на: комментарий от Siborgium
import Data.Complex
import Data.List
import Data.Function

cs :: [(Integer, [[Complex Double]], Double)]
cs = [(0,[[0.4 :+ 0.1],[0.4 :+ 0.1]],0.8),(1,[[0.6 :+ 0.01],[0.7 :+ 0.1]],0.4),(2,[[0.4 :+ 0.4],[0.4 :+ 0.4]],0.5),(3,[[0.6 :+ 0.4],[0.6 :+ 0.4]],0.8),(4,[[0.4 :+ (-0.4)],[0.3 :+ 0.3]],0.8),(5,[[0.7 :+ 0.4],[(-0.3) :+ 0.3]],0.4),(6,[[0.6 :+ 0.2],[(-0.2) :+ 0.2]],0.8)]

task :: Eq a1 => [(a2, b, a1)] -> [[(a2, b, a1)]]
main :: IO ()
task cs = map (\ q -> filter (\ (_,_,x) -> x==q) cs) xs
          where xs = nub $ map (\(_,_,x) -> x) cs
main = print $  task cs

И я получаю список cs (он сортируется относительно последнего элемента),

[[(0,[[0.4 :+ 0.1],[0.4 :+ 0.1]],0.8),(3,[[0.6 :+ 0.4],[0.6 :+ 0.4]],0.8),(4,[[0.4 :+ (-0.4)],[0.3 :+ 0.3]],0.8),(6,[[0.6 :+ 0.2],[(-0.2) :+ 0.2]],0.8)],[(1,[[0.6 :+ 1.0e-2],[0.7 :+ 0.1]],0.4),(5,[[0.7 :+ 0.4],[(-0.3) :+ 0.3]],0.4)],[(2,[[0.4 :+ 0.4],[0.4 :+ 0.4]],0.5)]]

из него мне нужно создать новый список из его вторых элементов.

[[0.4 :+ 0.1],[0.4 :+ 0.1]],[[0.6 :+ 0.4],[0.6 :+ 0.4]],[[0.4 :+ (-0.4)],[0.3 :+ 0.3]],[[0.6 :+ 0.2],[(-0.2) :+ 0.2]],[[0.6 :+ 1.0e-2],[0.7 :+ 0.1]],[[0.7 :+ 0.4],[(-0.3) :+ 0.3]],0.4)],[[0.4 :+ 0.4],[0.4 :+ 0.4]]

simona ()
Ответ на: комментарий от simona

Стесняюсь спросить, а зачем столько списков? Второй элемент триплета – всегда список из двух списков по одному комплексному числу в каждом. Проще было бы распаковать все это в [(Integer, Complex Double, Complex Double, Double)]. Или какую-нибудь структурку придумать. Кроме того, типы принято писать непосредственно перед функцией, которую они описывают.

из него мне нужно создать новый список из его вторых элементов.

task cs порождает список списков, как ты и пишешь в его типе. Поэтому паттерн матчинг проваливается – ты работаешь так, будто это все еще список туплов, но это уже список списков туплов. Как конкретно ты будешь с этим работать зависит от того, что тебе нужно. Навскидку можно сделать

a = map (\xs -> [x | (_, x, _) <- xs) $ task cs

получив список списков вторых элементов туплов.

Siborgium ()