由于使用'/'而没有出现(Fractional Int)的实例 [英] No instance for (Fractional Int) arising from a use of `/'

查看:179
本文介绍了由于使用'/'而没有出现(Fractional Int)的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Haskell的新手,我正在努力调试我的代码。
解决错误导致其他错误...

这是我的代码。

  import Data.Maybe 

data Op = Add | Sub | Mul | Div |和|或|不是|公式|较少|很棒的b $ b导出(Eq,Show)

数据Exp =文字值
| Primitive Op [Exp]
|变量字符串
|如果Exp Exp Exp
|让[(String,Exp)] Exp
导出(Show,Eq)

data Value = Number Int
| Bool Bool
| (String,Value)]

eval :: Env - > Exp - >价值
eval e(Literal v)= v
eval e(变量x)= fromJust(查找x e) - 22

prim :: Op - > [价值] - > Value
prim添加[Number a,Number b] = Number(a + b)
prim并且[Bool a,Bool b] = Bool(a& b)
prim Sub [数字a,Nuamber b] =数字(a - b) - 由于使用`/'
prim Mul [数字a,数字b] =数字(a * b) )
prim Div [Number a,Number b] = Number(a / b)
prim或[Bool a,Bool b] = Bool(a || b)
prim不[Bool a] = Bool(不是a)
prim等式[数字a,数字b] = Bool(a == b)
prim等式[String a,String b] = Bool(a == b)
prim [数字a,数字b] =布尔(a< b)
数组[b] bool(a< b)
a,Number b] = Bool(a> b)
prim Great [String a,String b] = Bool(a> b) - 37

main = do
eval [(y,(Number 40))](Let [(x,(Literal(Number 2)))](prim Add [(变量x),(变量y)] )) - 无法与实际类型为Value的期望类型Exp匹配

我是现在越来越我在评论中写了两个错误。
如果您知道我的代码有什么问题,请分享您的想法并节省我的时间......

非常感谢。

解决方案

   - 没有使用`/'

假设这是来自这一行,而不是你的评论:

  prim Div [数字a,数字b] =数字(a / b)



a b Int 秒。除法运算符是(/):: Fractional a => a - > a - >一个(你可以通过启动ghci并输入:t(/)或者通过在Hoogle上查看)。



如果您还没有看到小数a => a - > a - >一个,您应该分两部分阅读:


  1. 上下文小数a

  2. 类型 a - > a - > a

这就像常规 a - > a - >一个类型,所以它需要一些类型的两个参数,并给你返回相同类型的结果。添加小数a 上下文的唯一区别在于,用于 a 的类型必须是小数类型类;如果您还没有了解类型类别,请不要担心。如果您没有了解类型类别,请不要担心。他们很容易掌握,但不是你刚开始时应该深入研究的东西;
$ b

Int 不是的成员,小数类型的类,所以 / 操作符在 Int s上不起作用。 / p>

原因是常规数学除法不能用于这种类型的整数; 3/2 必须给 1.5 ,在这种情况下,它不适合类型 Int - > Int - > Int ,或给 1 2 ,在这种情况下它不会是正确的数学分工。有一个函数 div 用于实现整数除法,可以像 a`div` b 中缀表示法使用。

   - 无法与实际类型为'Value'的期望类型'Exp'匹配

这个消息是关于你自己的类型,用你写的单个表达式。实际的完整错误信息会给你更多关于表达式的哪一部分包含错误的上下文。只需从上往下按顺序,自己检查事物的类型,错误就会很快地跳到你身上。



在这种情况下,您可以在这里:

 令[(x,(Literal(Number 2)))](prim Add [(Variablex), (变量y)])

需要两个参数,一个 [(String,Exp)] 和一个 Exp 。列表没问题,但第二个参数是(prim Add [(Variablex),(Variabley)])。如果没有深入了解它的子结构以查看它是否正确, prim 的类型为 Op - > [价值] - >值,所以它不会给你一个 Exp



解决这个问题取决于你;看起来您需要在整个表达式/值区分中重构一些。 prim 给你一个,你可以简单地在 Literal 让你越过你得到的类型错误,但是你遇到了 prim 应该使用 Op 和一个 [Value] ,但您似乎已给它一个 Op 和一个 [Exp] (包含变量)。我认为你需要考虑使用 prim 来计算原始应用程序的结果,使用 Primitive Exp to 的构造函数表示一个原始应用程序,并使用 eval 来评估(在环境)一个任意表达式(可能包含几个原始应用程序)到一个值。


I am new to Haskell, and I am struggling with debugging my code. Fixing an error leads to other errors...

Here is my code.

import Data.Maybe

data Op = Add | Sub | Mul | Div | And | Or | Not | Eq | Less | Great
    deriving (Eq, Show)

data Exp = Literal Value
     | Primitive Op [Exp]
     | Variable String
     | If Exp Exp Exp
     | Let [(String, Exp)] Exp
    deriving (Show, Eq)

data Value = Number Int
       | Bool Bool
       | String String
    deriving (Eq, Show)

type Env = [(String, Value)]

eval :: Env -> Exp -> Value
eval e (Literal v) = v
eval e (Variable x) = fromJust (lookup x e)   --22

prim :: Op -> [Value] -> Value
prim Add [Number a, Number b] = Number (a + b)
prim And [Bool a, Bool b] = Bool (a && b)
prim Sub [Number a, Nuamber b] = Number (a - b)   -- No instance for (Fractional Int) arising from a use of `/'
prim Mul [Number a, Number b] = Number (a * b)
prim Div [Number a, Number b] = Number (a / b)
prim Or [Bool a, Bool b] = Bool (a || b)
prim Not [Bool a] = Bool (not a)
prim Eq [Number a, Number b] = Bool (a == b)
prim Eq [String a, String b] = Bool (a == b) 
prim Less [Number a, Number b] = Bool (a < b)
prim Less [String a, String b] = Bool (a < b)
prim Great [Number a, Number b] = Bool (a > b)
prim Great [String a, String b] = Bool (a > b) --37

main = do
    eval [("y", (Number 40))] (Let [("x", (Literal (Number 2)))] (prim Add [(Variable "x"), (Variable "y")])) -- Couldn't match expected type `Exp' with actual type `Value'

I am now getting two errors which I wrote in comments. If you know what's wrong with my code, please share your idea and save my time...

Thank you very much.

解决方案

-- No instance for (Fractional Int) arising from a use of `/'

Presumably that's coming from this line rather than the one with your comment:

prim Div [Number a, Number b] = Number (a / b)

a and b are Ints. The division operator is (/) :: Fractional a => a -> a -> a (you can find that out by firing up ghci and entering :t (/), or by looking it up on Hoogle).

If you haven't seen types like Fractional a => a -> a -> a, you should read this in two parts:

  1. The context Fractional a
  2. The type a -> a -> a

This is just like a regular a -> a -> a type, so it takes two arguments of some type and gives you back a result of the same type. The only difference in adding the Fractional a context is that type used for a must be an instance of the Fractional type class; it isn't free to range over any type you like.

If you haven't learned about type classes yet don't worry. They're pretty easy to grasp, but not something you should be looking at in depth when you're just starting; you'll get to them later.

Int isn't a member of the Fractional type class, so the / operator doesn't work on Ints.

The reason is that regular mathematical division doesn't work on integers with this type; 3 / 2 would have to either give 1.5, in which case it doesn't fit the type Int -> Int -> Int, or give 1 or 2, in which case it wouldn't be correct mathematical division. There is a function div for implementing integer division, usable like a `div` b in infix notation.

-- Couldn't match expected type `Exp' with actual type `Value'

This message is about your own types, in a single expression you wrote. And the actual full error message would have given you more context about which part of the expression contains the error. Just follow it through from the top down, checking the types of things yourself and the error very quickly leaps out at you.

In this case, you get to here:

Let [("x", (Literal (Number 2)))] (prim Add [(Variable "x"), (Variable "y")])

Let needs two arguments, a [(String, Exp)] and an Exp. The list is fine, but the second argument is (prim Add [(Variable "x"), (Variable "y")]). Without even digging into the substructure of that to see if it's correct, prim has type Op -> [Value] -> Value, so there's no way it's going to give you an Exp.

How to fix that is up to you; it looks like you need a bit of a refactor across the whole expression/value distinction. prim gives you an Value, which you could simply apply wrap in a Literal to get you past the type error you're getting, but then you run into the problem that prim should be taking an Op and a [Value], but you appear to have given it an Op and a [Exp] (containing variables). I think you need to think about the difference between using prim to compute the results of a primitive application, using the Primitive constructor of Exp to represent a primitive application, and using eval to evaluate (in an environment) an arbitrary expression (which may contain several primitive applications) to a value.

这篇关于由于使用'/'而没有出现(Fractional Int)的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆