Haskell. Вопрос ламера....
От: Sergey J. A. Беларусь  
Дата: 15.12.05 14:08
Оценка:
xlist = xlist' 1
xlist' x = x:(xlist' ((x + 2) * (0 - 1)) )


По моим представлениям должна выдвать [1, -3, 5, -7, ...]
Но выдаёт [1, -3, 1, -3, ...]

Если убрать умножение на -1, то всё работает — выдаёт 1, 3, 5 ...

Где я туплю ?

З.Ы. А вот так работает:

xlist = xlist' 1
xlist'  x =  x:(xlist'' (x + 2) )
xlist'' x = -x:(xlist'  (x + 2) )
Re: Haskell. Вопрос ламера....
От: Quintanar Россия  
Дата: 15.12.05 14:16
Оценка: 28 (2) +1
Здравствуйте, Sergey J. A., Вы писали:

SJA>
SJA>xlist = xlist' 1
SJA>xlist' x = x:(xlist' ((x + 2) * (0 - 1)) )
SJA>


SJA>По моим представлениям должна выдвать [1, -3, 5, -7, ...]

SJA>Но выдаёт [1, -3, 1, -3, ...]

SJA>Если убрать умножение на -1, то всё работает — выдаёт 1, 3, 5 ...


SJA>Где я туплю ?


Потому что (-3 + 2)*(-1) = 1
Re: Haskell. Вопрос ламера....
От: Кодт Россия  
Дата: 15.12.05 15:00
Оценка:
Здравствуйте, Sergey J. A., Вы писали:
xlist = [ (k*2+1)*(1-2*(k`mod`2)) | k <- [0..] ]

Перекуём баги на фичи!
Re[2]: Haskell. Вопрос ламера....
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 15.12.05 15:26
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Sergey J. A., Вы писали:

К>
К>xlist = [ (k*2+1)*(1-2*(k`mod`2)) | k <- [0..] ]
К>

К>

xlist = 1:zipWith (flip (-)) xlist (cycle [-2,2])

Re[2]: Haskell. Вопрос ламера....
От: Sergey J. A. Беларусь  
Дата: 15.12.05 18:17
Оценка:
Здравствуйте, Кодт, Вы писали:

К>
К>xlist = [ (k*2+1)*(1-2*(k`mod`2)) | k <- [0..] ]
К>

К>

Эт ещё слишком сложно для меня...
... << RSDN@Home 1.2.0 alpha rev. 619>>
Re[3]: Haskell. Вопрос ламера....
От: Трурль  
Дата: 16.12.05 06:43
Оценка: 4 (1)
Здравствуйте, Sergey J. A., Вы писали:

SJA>Эт ещё слишком сложно для меня...

А так?

a= 1:(-1):a
b= [1,3..]
xlist = zipWith (*) a b
Re: Haskell. Вопрос ламера....
От: reductor  
Дата: 16.12.05 08:03
Оценка:
Здравствуйте, Sergey J. A., Вы писали:

SJA>З.Ы. А вот так работает:


SJA>
SJA>xlist = xlist' 1
SJA>xlist'  x =  x:(xlist'' (x + 2) )
SJA>xlist'' x = -x:(xlist'  (x + 2) )
SJA>



ну еще можно так:

xlist x even next = x : x' * even : xlist (next x') even next
    where x' = next x

-- xlist 1 (-1) (+2)


Ну и Трурль там более красивый способ показал :)
Re: Haskell. Вопрос ламера....
От: Костя Ещенко Россия  
Дата: 16.12.05 13:37
Оценка:
Здравствуйте, Sergey J. A., Вы писали:

С каждого по варианту! Выриант Трурля красив, но я бы предпочел что-нибудь прямолинейное, типа этого
xlist = seqFrom 1
    where seqFrom x = x : (seqFrom $! if x>0 then -x-2 else -x+2)

Оператор вызова по значению $! устраняет ненужную ленивость — исключает возможность образования последовательности нуль-арных "функций", ссылающихся друг на друга, и тем самым не позволяющих освободить занимаемую ими память.
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re: Haskell. Вопрос ламера....
От: Sergey J. A. Беларусь  
Дата: 26.12.05 10:05
Оценка:
Ещё вопрос.

Решил немного разобратся с классами. Ввёл класс Reflection. К переменным с типом, относящимся к данному классу (или как правильно сказать ?) можно применить ф-ию typeof, возвращающую строковое представление типа.

class Reflection a where
    typeof :: a -> String

instance Reflection Char where
    typeof _ = "Char"

instance Reflection Bool where
    typeof _ = "Bool"

instance Reflection Integer where
    typeof _ = "Integer"

instance Reflection Int where
    typeof _ = "Int"

data Point a = Pt2D a a|Pt3D a a a

instance Reflection (Point a) where
    typeof (Pt2D _ _) = "Point2D"
    typeof (Pt3D _ _ _) = "Point3D"

typeofInt :: Int -> String
typeofInt x = typeof x

typeofInteger :: Integer -> String
typeofInteger x = typeof x


Почему-то typeofInt и typeofInteger работают и выводят что нужно, а вот если ввести typeof 22 (среда — Husg for Windows 32), то:

ERROR — Unresolved overloading
*** Type : (Num a, Reflection a) => [Char]
*** Expression : typeof 22


В чём засада ?
Re[2]: Haskell. Вопрос ламера....
От: Кодт Россия  
Дата: 26.12.05 13:26
Оценка: 4 (1)
Здравствуйте, Sergey J. A., Вы писали:

SJA>Почему-то typeofInt и typeofInteger работают и выводят что нужно, а вот если ввести typeof 22 (среда — Husg for Windows 32), то:

SJA>ERROR — Unresolved overloading
SJA>*** Type : (Num a, Reflection a) => [Char]
SJA>*** Expression : typeof 22

SJA>В чём засада ?

Потому что числовой литерал 22 сам по себе не имеет типа; это как бы полиморфная функция без параметров.
Prelude> :t 22
22 :: Num a => a

Возникает неоднозначность, поскольку из typeof 22 вытекает лишь ограничение Reflection a.

Аналогично:
module Test
where

f :: (Num a) => () -> a
f = f -- вычислять эту функцию нельзя, но тип она имеет :)
g = f ()

------------
--- Hugs ---

Test> :t g
g :: Num a => a

Test> :t (g + 1/2)
g + 1 / 2 :: Fractional a => a  -- Fractional является подклассом Num, поэтому произвели уточнение

Test> :t (g>>g)
g >> g :: (Monad a, Num (a b)) => a b -- конъюнкция ограничений


Вот если ты напишешь модуль, где будут определены глобальные константы
module Test
where

x = 22      -- тип x зависит от defaults текущего модуля, и обычно равен Integer
y = 22::Int -- явное указание типа

------------
--- Hugs ---

Test> :t x
x :: Integer

Test> :t y
y :: Int
Перекуём баги на фичи!
Re[3]: Haskell. Вопрос ламера....
От: Sergey J. A. Беларусь  
Дата: 27.12.05 15:59
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Потому что числовой литерал 22 сам по себе не имеет типа; это как бы полиморфная функция без параметров.

К>
К>Prelude> :t 22
К>22 :: Num a => a
К>

К>Возникает неоднозначность, поскольку из typeof 22 вытекает лишь ограничение Reflection a.

Тут вроде немного понял... Т.е. выражение typeof 22 не вычисляется до конца, т.к. интерпретатор не может выбрать какой тип подставить вместо a и завершить вычисление:

(Reflection a, Num a) => [Char]

Аналогично 22:

Num a => a

это выражение не "вычислится" пока мы не уточним тип. Например: 22::Int, либо интерпретатору не станет ясно, какой тип от 'ф-ии' 22 ожидается.
Но что тогда в этом выражении означает :: ? Я не нашёл ничего в документации кроме использования :: в объявлениях типов. Тем более, что следующий код не работает:

(typeof 22)::Int


Хотя, только что заметил, что, если бы тип выражения был

(Reflection a, Num a) => a

То (typeof 22)::Int срабатывает как и ожидалось

В дальнейшем коде я пока не смог разобратся, однако есть некоторое несоответствие:
К>Аналогично:
К>
К>module Test
К>where

К>f :: (Num a) => () -> a
К>f = f -- вычислять эту функцию нельзя, но тип она имеет :)
К>g = f ()

К>------------
К>--- Hugs ---

Test>> :t g
К>g :: Num a => a
К>


А у меня получается:

Main> :t g
g :: Integer

Re[3]: Haskell. Вопрос ламера....
От: Sergey J. A. Беларусь  
Дата: 27.12.05 17:02
Оценка:
Здравствуйте, Кодт, Вы писали:

Всё, я догнал, что происходит в Вашем примере. Вот только не понял, зачем так запутано ? Вроде должно хватить:

f :: (Num a) => a
f = f

И далее:

Main> :t f
f :: Num a => a

Main> :t (f + 1)
f + 1 :: Num a => a

Main> :t (f + 1/2)
f + 1 / 2 :: Fractional a => a


Зачем g, () ... ? Я в смятении
Re[4]: Haskell. Вопрос ламера....
От: Кодт Россия  
Дата: 28.12.05 10:24
Оценка: 4 (1)
Здравствуйте, Sergey J. A., Вы писали:

SJA>Здравствуйте, Кодт, Вы писали:


SJA>Всё, я догнал, что происходит в Вашем примере. Вот только не понял, зачем так запутано ? Вроде должно хватить:


Да... это на меня нашло помутнение. Конечно же, достаточно было f:(Num a)=>a

По поводу :: в выражениях. Этот оператор конкретизирует тип полиморфного выражения и используется
— когда нужно устранить неоднозначность,
— для уточнения типа результата,
— для направления вывода типов в нужное русло.

module Test
where

ex x y z = (x+y, z+1)       -- (Num a, Num b) => a->a->b -> (a,b)               Это полиморфная функция
ex' = ex                    -- Integer->Integer->Integer -> (Integer,Integer)   Константа, по умолчанию тип конкретизирован

ex'' :: (Num a) => a->a->a -> (a,a)
ex'' = ex                   -- (Num a) => a->a->a -> (a,a)                      Принудительно сделали полиморфную константу

ex1 y z = ex 10 y z         -- (Num a, Num b) => a->b -> (a,b)
ex1' = ex 10                -- Integer->Integer -> (Integer,Integer)
ex1'' = ex'' 10             -- Integer->Integer -> (Integer,Integer)

ex2 y z = ex (10::Int) y z  -- (Num b) => Int->b -> (Int,b)                     Полиморфная функция, тип одного аргумента (и результата) конкретный
ex2' = ex (10::Int)         -- Int->Integer -> (Int,Integer)                    Константа, обратите внимание на тип
ex2'' = ex'' (10::Int)      -- Int->Int -> (Int,Int)

Перекуём баги на фичи!
Re: Haskell. Вопрос ламера....
От: Adopt  
Дата: 05.01.06 22:36
Оценка:
Здравствуйте, Sergey J. A., Вы писали:

SJA>
SJA>xlist = xlist' 1
SJA>xlist' x = x:(xlist' ((x + 2) * (0 - 1)) )
SJA>


немного читал документацию по Haskell...

но что такое xlist'? всмысле ' после имени функции
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Haskell. Вопрос ламера....
От: Sergey J. A. Беларусь  
Дата: 06.01.06 07:53
Оценка:
Здравствуйте, Adopt, Вы писали:

SJA>>
SJA>>xlist = xlist' 1
SJA>>xlist' x = x:(xlist' ((x + 2) * (0 - 1)) )
SJA>>


A>немного читал документацию по Haskell...


A>но что такое xlist'? всмысле ' после имени функции


Ну, я прочитал, что ' можно использовать в имени. И обычно используется для именования "дополнительных" ф-ий. Так что вместо xlist' можно было бы взять и любое другое имя, например xlistImpl
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.