LINUX.ORG.RU

[Haskell] first steps...

 


0

0

Всем привет... уже довольно давно начал интересоваться функциональными и почти функциональными языками программирования... можно сказать освоил азы lisp и erlang, решил подробнее остонавиться на haskell, пока только "напосмотреть"...

мой первый опыт так сказать:

$ cat qwe.hs module Main where

factorial n = fac n 1

fac 0 acc = acc

fac n acc = fac (n - 1) (n * acc)

main = factorial 100000

при попытке скомпилировать это, получаю следущее:

$ ghc qwe.hs -o qwe

qwe.hs:9:17: No instance for (Num (IO a)) arising from the literal `100000' at qwe.hs:9:17-22 Possible fix: add an instance declaration for (Num (IO a)) In the first argument of `factorial', namely `100000' In the expression: factorial 100000 In the definition of `main': main = factorial 100000

мой естественный вопрос - что я делаю не так? :)

понятно, я невежественнен, и не дочитал основы haskell, не въехал до конца в систему типов и т.д... но обещаю, я исправлюсь :) вы только мне конкретно с этим примером объясните, как оно должно выглядеть?

если написать

main = print (factorial 100000)

то оно работает, но я именно не хочу выводить результат, как это сделать?

Зарание всем спасибо!

агрх... форматирование...

мой код

module Main where

factorial n = fac n 1

fac 0 acc = acc

fac n acc = fac (n - 1) (n * acc)

main = do factorial 100000


ошибка:

ghc qwe.hs -o qwe

qwe.hs:9:17:
    No instance for (Num (IO a))
      arising from the literal `100000' at qwe.hs:9:17-22
    Possible fix: add an instance declaration for (Num (IO a))
    In the first argument of `factorial', namely `100000'
    In the expression: factorial 100000
    In the definition of `main': main = factorial 100000

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

=) да ладно тебе, не ругайсо %)

я так понимаю вся бяда в том, что тип у main IO() ? и поэтому оно должно всего хоть что-нить, но выводить? если не прав, то поправь пожалуйста.

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

Я тоже в шутку :).

> я так понимаю вся бяда в том, что тип у main IO()

Так точно, только не выводить, а делать что-либо.

Полагаю эффективно ничего не делать будет:

main = return ()

Монады синтаксически сложнее функций, по-этому написать как функцию 1-в-1 не получится.

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

спасибо за разьяснения! обязательно в отпуске подробнее почитаю и про манады и про систему типов :)

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

И ещё один вопрос, а если я пишу так:

module Main where

factorial n = fac n 1

fac 0 acc = acc

fac n acc = fac (n - 1) (n * acc)

main = return (factorial 100000)

оно вообще хоть что-нить считает? или тут работает ленивость, и оно просто забивает на вычисления и выходит из программы? Если так, то как можно заставить отработать функцию?

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

main = putStrLn $ show $ factorial 100000

или (что тоже самое):

main = putStrLn(show(factorial 100000))

factorial вычисялет факториал, show преобразовывает полученное число в строку, putStrLnвыводит строку на стандартный вывод.

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

>> Мне надо не выводить результат, хочу посчитать, но не распечатывать ;)

Ну тогда загрузи этот код в GHCi и выполни factotial 100000

А вообще очень рекомендую к прочтению "Haskell, the craft of functional programming" - для начинающих просто замечательная книга. Разжевано все достаточно популярно без углублений в теорию и с огромным количеством упражнений. Рекомендую потому, что эта книга легко находится в pdf в инете (в отличие от hsoe например). Хотя мне ее было намного легче читать после SICP :))

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

>> Ну тогда загрузи этот код в GHCi и выполни factotial 100000

Убрав предваритеьлно main = ...

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

Ну так я уже делал :) просто для меня было удивительно, что этого нельзя сделать в main... ок, спасибо большое!

/me пошёл читать умные книжки...

Cy6erBr4in ★★★
() автор топика

> то оно работает, но я именно не хочу выводить результат, как это сделать?

No way, haskell is lazy language. It won't work if you don't want to see results.

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

>> просто для меня было удивительно, что этого нельзя сделать в main... ок, спасибо большое!

Как уже писали main 'возвращет' действия в терминах ввода-вывода, т.е. банально все что делает main это вводит и выводит данные :) Вычисление же факториала не является действием, все чем может помочь здесь main - это напечатать результат. Это особенность философии хаскеля.

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

>> No way, haskell is lazy language. It won't work if you don't want to see results.

Кстати это относится не только к ленивым. В том же си чтобы вычислить функцию надо, грубо говоря, потребовать от нее результат :) В виде вызова ессно :))

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

> Кстати это относится не только к ленивым. В том же си чтобы вычислить функцию надо, грубо говоря, потребовать от нее результат :) В виде вызова ессно :))

Один еврей много лет молился Богу, и все об одном v хотел выиграть в лотерею. v Господи, v говорил он, - ну почему Исаак выигрывал в лотерею, Абрам выигрывал, а я сколько лет тебе молюсь, никак не могу выиграть. Бог не выдержал, и раздался голос с небес: v Я с радостью помогу тебе. Но ты хоть раз купи лотерейный билет!

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

> Впрочем, поскольку факториал у тебя ленивый, скорее всего, оно просто вылетит.

Всегда можно заставить :]

main = do let !x = product [1..10^7] -- еще и стека не хватит
               return () 

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

Кто бы спорил, эту ошибку все новички совершают.

Miguel ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.