相关疑难解决方法(0)

类型检查器允许非常错误的类型替换,程序仍然编译

在尝试调试我的程序中的问题时(使用Gloss将2个具有相同半径的圆圈绘制成不同的大小),我偶然发现了一个奇怪的情况.在我处理对象的文件中,我有以下定义*:

type Coord = (Float,Float)
data Obj =  Player  { oPos :: Coord, oDims :: Coord }
Run Code Online (Sandbox Code Playgroud)

在导入Objects.hs的主文件中,我有以下定义:

startPlayer :: Obj
startPlayer = Player (0,0) 10
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为我为玩家添加和更改字段,并且忘记更新Player之后(其尺寸由单个数字确定以表示半径,但我将其更改为a startPlayer来表示(宽度,高度);如果我做的话玩家对象是一个非圆圈).

令人惊奇的是,上面的代码编译并运行,尽管第二个字段是错误的类型.

我首先想到的可能是我打开了不同版本的文件,但对编译程序中的任何文件的任何更改都会反映出来.

接下来我认为可能Coord由于某种原因没有被使用.注释会startPlayer产生编译器错误,甚至更奇怪的是,更改startPlayerin 10会导致适当的响应(更改起始大小startPlayer); 再次,尽管它是错误的类型.为了确保它正确读取数据定义,我在文件中插入了一个拼写错误,它给了我一个错误; 所以我正在查看正确的文件.

我试图粘贴2段以上的到自己的文件,并吐出预期误差的第二场PlayerPlayer是不正确.

什么可能允许这种情况发生?您认为这是Haskell的类型检查器应该阻止的事情.


我应该注意到,我原来的问题的答案,即两个被认为是相同半径的圆被绘制成不同的大小,其中一个半径实际上是负的.

haskell types

98
推荐指数
2
解决办法
3569
查看次数

是否有一个被认为是"安全"的GHC扩展名单?

有时,如果没有至少一种语言扩展,我想写的一段代码是不合法的.当试图在研究论文中实现这些想法时尤其如此,这些论文倾向于使用在撰写论文时可用的任何spiffy,超扩展版本的GHC,而没有明确实际需要哪些扩展.

结果是我经常在我的.hs文件的顶部找到这样的东西:

{-# LANGUAGE TypeFamilies
           , MultiParamTypeClasses
           , FunctionalDependencies
           , FlexibleContexts
           , FlexibleInstances
           , UndecidableInstances
           , OverlappingInstances #-}
Run Code Online (Sandbox Code Playgroud)

我不介意,但我常常觉得我正在做出盲目的牺牲来安抚GHC的大神.它抱怨如果没有语言扩展X,某段代码无效,所以我为X添加了一个pragma.然后它要求我启用Y,所以我为Y添加了一个pragma.到这个结束时,我已经启用我不太了解的三个或四个语言扩展,我不知道哪些是"安全的".

用"安全"来解释我的意思:

  • 我明白这UndecidableInstances是安全的,因为虽然它可能导致编译器不终止,只要代码编译它就不会有意想不到的副作用.

  • 另一方面,OverlappingInstances显然是不安全的,因为它使我很容易意外地编写产生运行时错误的代码.

所以我的问题是:

是否有GHCextensions列表被认为是"安全的"并且"不安全"?

haskell ghc

36
推荐指数
1
解决办法
2097
查看次数

明确导入实例

如何显式导入类型类实例?另外,如何使用合格的导入进行此操作?

目前,我正在做

import Control.Monad.Error ()
Run Code Online (Sandbox Code Playgroud)

导入我可以用于的monad实例(Either String).以前,我用过

import Control.Monad.Error
Run Code Online (Sandbox Code Playgroud)

我对其中任何一个都不满意,因为Monad实例是隐式导入的.

import haskell typeclass

32
推荐指数
2
解决办法
7330
查看次数

如何导入模块隐藏子模块或实例?

有了这个代码

import Control.Monad
import Control.Applicative
import Control.Monad.State

class DefVal a where
  defVal :: a

instance (DefVal a) => Alternative (Either a) where
  empty = Left defVal
  (Left _) <|> x = x
  x        <|> _ = x

instance (DefVal a) => MonadPlus (Either a) where
  mzero = empty
  mplus = (<|>)

newtype ErrString = ErrString { toString :: String }
  deriving Show

instance DefVal ErrString where
  defVal = ErrString "Default Error String"
Run Code Online (Sandbox Code Playgroud)

我收到错误消息:

Duplicate instance declarations:
  instance DefVal a => …
Run Code Online (Sandbox Code Playgroud)

import haskell module

4
推荐指数
1
解决办法
1225
查看次数

标签 统计

haskell ×4

import ×2

ghc ×1

module ×1

typeclass ×1

types ×1