Haskell GHC版本差异-编译错误

Haskell GHC版本差异-编译错误,haskell,ghc,fibonacci,Haskell,Ghc,Fibonacci,我在练习Haskell时遇到了一个奇怪的问题,我在互联网上找不到解决办法。我决定解决这个问题: 在我能想到的很多方面。一种方法是使用memonization执行递归,其中我希望使用状态monad作为缓存。我的Windows 10上有GHC 7.10.2,Ubuntu 14.04上有GHC 7.6.2。下面的代码在7.6.2上编译(并且运行得很好),在7.10.2上编译时不会出现错误,无论我在哪里键入“Map”,例如: 不在范围内:类型构造函数或类:“Map.Map” 不在范围内:“Map.lo

我在练习Haskell时遇到了一个奇怪的问题,我在互联网上找不到解决办法。我决定解决这个问题:

在我能想到的很多方面。一种方法是使用memonization执行递归,其中我希望使用状态monad作为缓存。我的Windows 10上有GHC 7.10.2,Ubuntu 14.04上有GHC 7.6.2。下面的代码在7.6.2上编译(并且运行得很好),在7.10.2上编译时不会出现错误,无论我在哪里键入“Map”,例如:

不在范围内:类型构造函数或类:“Map.Map”

不在范围内:“Map.lookup”

问题是使用第二行执行的很糟糕。我不知道我在哪里犯了一个错误,但我认为它应该以线性时间运行,并带有记忆。然而,有了这条线,我的算法显然是指数的(我甚至不能得到第50个Fib数的答案——那么长)。在这种情况下我做错了什么

更新 感谢你的评论,我修正了我的代码。显然,
mod
函数有问题(我完全不知道这是如何在GHC 7.6.2上编译的)。我也改变了:

import qualified Data.Map as Map
致:

现在,以下代码按预期工作:

module Main (
    main
) where

import qualified Data.Map.Strict as Map
import Control.Monad.State

type CacheState = Map.Map Int Int
type IOState a = StateT CacheState IO a

modNum :: Int
modNum = 100000007

fibsMod :: [Int]
fibsMod = 0 : 1 : zipWith (\x y -> (x + y) `mod` modNum) fibsMod (tail fibsMod)

-- | calculate Fibs with memoization in map
memoizedFib :: Int -> IOState Int
memoizedFib n = do
    state <- get
    let x = Map.lookup n state
    case x of
        Just y ->
            return y
        Nothing -> do
            n1 <- memoizedFib (n - 1)
            n2 <- memoizedFib (n - 2)
            state <- get
            let n3 = mod (n1 + n2) modNum
            put (Map.insert n n3 state)
            return n3


query :: [Int] -> IOState ()
query [] = return ()
query (n:ns) = do
    fibNum <- memoizedFib n
    liftIO $ print fibNum
    query ns


main :: IO ()
main = do
    inputdata <- getContents
    let intList = (map (read :: String -> Int) . tail . words) inputdata

    evalIOState $ query intList
    where
        initState :: Int -> Map.Map Int Int
        --initState upTo = Map.fromList $ zip [0 .. upTo] $ take upTo fibsMod
        initState upTo = Map.fromList [(0, 0), (1, 1)]

        evalIOState :: IOState a -> IO a
        evalIOState m = evalStateT m (initState 10001)
主模块(
主要的
)在哪里
导入符合条件的Data.Map.Strict作为映射
进口控制单体状态
键入CacheState=Map.Map Int
类型IOState a=StateT CacheState IO a
modNum::Int
modNum=100000007
fibsMod::[Int]
fibsMod=0:1:zipWith(\xy->(x+y)`mod`modNum)fibsMod(tail fibsMod)
--|在map中通过记忆计算FIB
memorizedFib::Int->IOState Int
memoizedFib n=do
陈述
返回y
无事可做

n1问题无法通过复制和粘贴到文件中进行复制。但是有一个不同的明显错误,在
mod
周围缺少反勾号。这是您的真实代码吗?对于您报告的问题,我立即猜测您在
导入
语句中有错误。
put(Map.insert n n3 state)
使用计算
n1
n2
之前的
状态
,因此,您将丢弃递归中的所有记忆。您显示的代码不应包含该错误。正如@ReidBarton所说,也许这不是您真正的代码?我的猜测是,windows计算机上的代码实际上读取了
导入符合条件的数据.Map
,并将
作为Map
部分删除。您是否专门尝试更改工作代码以使用数据.Map?因为对于您报告的行为没有合理的解释:很可能是您构建了错误版本的代码。(或者您以某种非常具体且不太可能的方式破坏了7.10.2安装。)
import qualified Data.Map as Map
import qualified Data.Map.Strict as Map
module Main (
    main
) where

import qualified Data.Map.Strict as Map
import Control.Monad.State

type CacheState = Map.Map Int Int
type IOState a = StateT CacheState IO a

modNum :: Int
modNum = 100000007

fibsMod :: [Int]
fibsMod = 0 : 1 : zipWith (\x y -> (x + y) `mod` modNum) fibsMod (tail fibsMod)

-- | calculate Fibs with memoization in map
memoizedFib :: Int -> IOState Int
memoizedFib n = do
    state <- get
    let x = Map.lookup n state
    case x of
        Just y ->
            return y
        Nothing -> do
            n1 <- memoizedFib (n - 1)
            n2 <- memoizedFib (n - 2)
            state <- get
            let n3 = mod (n1 + n2) modNum
            put (Map.insert n n3 state)
            return n3


query :: [Int] -> IOState ()
query [] = return ()
query (n:ns) = do
    fibNum <- memoizedFib n
    liftIO $ print fibNum
    query ns


main :: IO ()
main = do
    inputdata <- getContents
    let intList = (map (read :: String -> Int) . tail . words) inputdata

    evalIOState $ query intList
    where
        initState :: Int -> Map.Map Int Int
        --initState upTo = Map.fromList $ zip [0 .. upTo] $ take upTo fibsMod
        initState upTo = Map.fromList [(0, 0), (1, 1)]

        evalIOState :: IOState a -> IO a
        evalIOState m = evalStateT m (initState 10001)