2016-02-11 3 views
0

Я знаю, что этот вопрос возник раньше, но ответ в this question по какой-то причине не работает для меня. Мой пример следующий код:Haskell Int to String

fiblist = 0 : 1 : (zipWith (+) fiblist (tail fiblist)) 

fib :: (Integral a) => a -> String 
fib n 
    | n < 10000 = show (fiblist !! n) 
    | otherwise = error "The number is too high and the calculation might freeze your machine." 

Я пытаюсь преобразовать элемент с индексом n в строку, так что функция соответствует его подписи, но я получаю следующее сообщение об ошибке:

MyLib.hs:63:34: 
    Couldn't match expected type ‘Int’ with actual type ‘a’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for fib :: Integral a => a -> String 
      at MyLib.hs:61:8 
    Relevant bindings include 
     n :: a (bound at MyLib.hs:62:5) 
     fib :: a -> String (bound at MyLib.hs:62:1) 
    In the second argument of ‘(!!)’, namely ‘n’ 
    In the first argument of ‘show’, namely ‘(fiblist !! n)’ 
Failed, modules loaded: none. 

Итак, как я могу его преобразовать?

Edit # 1:

Я отдаю себе отчет в параметрах командной строки +RTS -M256m -K256m и такие, но они не похоже на работу для этого кода, он по-прежнему ест почти всю мою память, если n является слишком высоко. Различное поведение для length бесконечного списка, там аргументы командной строки работают и прекращают выполнение кода.

Edit # 2:

Я нашел способ импортировать genericIndex:

import Data.List 

, который я предполагаю, что это так же, как показано на here.

Теперь, когда я использую следующий код:

fib :: (Integral a) => a -> String 
fib n 
    | n < 10000 = genericIndex fiblist n 
    | otherwise = error "The number is too high and the calculation might freeze your machine." 

Я получаю следующее сообщение об ошибке:

MyLib.hs:64:11: 
    No instance for (Num String) arising from the literal ‘0’ 
    In the first argument of ‘(:)’, namely ‘0’ 
    In the expression: 0 : 1 : (zipWith (+) fiblist (tail fiblist)) 
    In an equation for ‘fiblist’: 
     fiblist = 0 : 1 : (zipWith (+) fiblist (tail fiblist)) 
Failed, modules loaded: none. 
+0

Есть намного более быстрые способы выполнения расчета. – dfeuer

+0

@dfeuer kinda offtopic, но меня это интересует. Не могли бы вы связать меня? – Zelphir

+0

На странице Haskell есть целая страница. Большой «ага!» один из них состоит в том, чтобы разбить последовательность на пары (1,1), (2,3), ... и понять, что вы можете получить от каждой пары к следующей путем умножения на одну и ту же матрицу. Тогда, поскольку матричное умножение ассоциативно, вы можете использовать возведение в степень путем возведения в квадрат, чтобы сделать его супер-быстрым - O (log n) дополнениями, чтобы получить n-й элемент, если я не ошибаюсь. – dfeuer

ответ

2

Так вы утверждаете fib полиморфные по всему экземпляру Integral, самое простое исправление возможно переключиться с (!!) на использование genericIndex, у которых есть эти сигнатуры:

(!!)   ::    [a] -> Int -> a 
genericIndex :: Integral i => [a] -> i -> a 
+0

Обновлен мой вопрос. – Zelphir

+1

@ Zelphir Вы изменили '(!!)' на 'genericIndex', но почему-то отказались от' show'! –

+0

Ha! Должно быть, я был слеп! Благодаря! Оно работает! – Zelphir