haskell 程序来查找两个列表之间的相似性

如何解决haskell 程序来查找两个列表之间的相似性

好的,所以我是 Haskell 的新手,我想编写一个程序,在该程序中我获取两个列表并找出它们之间的相似性(常见项目数/项目数)。 这是我目前所拥有的:

fun2 :: [Int]->[Int]->Float

fun2 [] xs2 = 0
fun2 xs1 xs2 = if head xs1 == head xs2 then (1/length xs2) + fun2 tail xs1 xs2
else if head xs1 /= head xs2 then fun2 xs1 tail xs2
else fun2 tail xs1 xs2

main = fun2 [1,2,3,4] [3,4,5,6]

让我解释一下我想要做什么,我定义了我的函数获取两个整数列表并输出一个浮点数(相似性百分比)。然后我编写我的函数,基本情况是当第一个列表为空时,而该函数会将第一个列表的每个元素与第二个列表的每个元素进行比较,如果找到匹配项,它将加 1 然后除以大小以获取百分比。 但是,当我运行此代码时,出现了很多错误

main.hs:4:45: error:
• Couldn't match expected type ‘Float’ with actual type ‘Int’
• In the expression: (1 / length xs2) + fun2 tail xs1 xs2
  In the expression:
    if head xs1 == head xs2 then
        (1 / length xs2) + fun2 tail xs1 xs2
    else
        if head xs1 /= head xs2 then
            fun2 xs1 tail xs2
        else
            fun2 tail xs1 xs2
  In an equation for ‘fun2’:
      fun2 xs1 xs2
        = if head xs1 == head xs2 then
              (1 / length xs2) + fun2 tail xs1 xs2
          else
              if head xs1 /= head xs2 then
                  fun2 xs1 tail xs2
              else
                  fun2 tail xs1 xs2

main.hs:4:62: error:
• Couldn't match expected type ‘[Int] -> Int’
              with actual type ‘Float’
• The function ‘fun2’ is applied to three arguments,but its type ‘[Int] -> [Int] -> Float’ has only two
  In the second argument of ‘(+)’,namely ‘fun2 tail xs1 xs2’
  In the expression: (1 / length xs2) + fun2 tail xs1 xs2

main.hs:4:67: error:
• Couldn't match expected type ‘[Int]’
              with actual type ‘[a0] -> [a0]’
• Probable cause: ‘tail’ is applied to too few arguments
  In the first argument of ‘fun2’,namely ‘tail’
  In the second argument of ‘(+)’,namely ‘fun2 tail xs1 xs2’
  In the expression: (1 / length xs2) + fun2 tail xs1 xs2

main.hs:5:39: error:
• Couldn't match expected type ‘[Int] -> Float’
              with actual type ‘Float’
• The function ‘fun2’ is applied to three arguments,but its type ‘[Int] -> [Int] -> Float’ has only two
  In the expression: fun2 xs1 tail xs2
  In the expression:
    if head xs1 /= head xs2 then
        fun2 xs1 tail xs2
    else
        fun2 tail xs1 xs2

main.hs:5:48: error:
• Couldn't match expected type ‘[Int]’
              with actual type ‘[a1] -> [a1]’
• Probable cause: ‘tail’ is applied to too few arguments
  In the second argument of ‘fun2’,namely ‘tail’
  In the expression: fun2 xs1 tail xs2
  In the expression:
    if head xs1 /= head xs2 then
        fun2 xs1 tail xs2
    else
        fun2 tail xs1 xs2

main.hs:6:10: error:
• Couldn't match expected type ‘[Int] -> Float’
              with actual type ‘Float’
• The function ‘fun2’ is applied to three arguments,but its type ‘[Int] -> [Int] -> Float’ has only two
  In the expression: fun2 tail xs1 xs2
  In the expression:
    if head xs1 /= head xs2 then
        fun2 xs1 tail xs2
    else
        fun2 tail xs1 xs2

main.hs:6:15: error:
• Couldn't match expected type ‘[Int]’
              with actual type ‘[a2] -> [a2]’
• Probable cause: ‘tail’ is applied to too few arguments
  In the first argument of ‘fun2’,namely ‘tail’
  In the expression: fun2 tail xs1 xs2
  In the expression:
    if head xs1 /= head xs2 then
        fun2 xs1 tail xs2
    else
        fun2 tail xs1 xs2

main.hs:8:1: error:
• Couldn't match expected type ‘IO t0’ with actual type ‘Float’
• In the expression: main
  When checking the type of the IO action ‘main’

所以你能告诉我我在这里做错了什么吗?

解决方法

main.hs:4:45: error:
• Couldn't match expected type ‘Float’ with actual type ‘Int’
• In the expression: (1 / length xs2) + fun2 tail xs1 xs2
  …

length 返回 Int

例如,在 GHCi 中:

> :type length
length :: Foldable t => t a -> Int

> :set -XTypeApplications
> :type length @[]
length @[] :: [a] -> Int

(请注意,我写了 > 来表示提示。您可以使用 :set prompt "> ":set prompt-cont "| " 将提示设置为相同的多行输入。)

虽然 (/) 适用于集合 Fractional 中的类型:

> :type (/)
(/) :: Fractional a => a -> a -> a

> :info Fractional
class Num a => Fractional a where
  (/) :: a -> a -> a
  recip :: a -> a
  fromRational :: Rational -> a
  {-# MINIMAL fromRational,(recip | (/)) #-}
    -- Defined in ‘GHC.Real’
instance forall a k (b :: k).
         Fractional a =>
         Fractional (Const a b)
  -- Defined in ‘Data.Functor.Const’
instance Fractional Float -- Defined in ‘GHC.Float’
instance Fractional Double -- Defined in ‘GHC.Float’

Int 不在 Fractional 中:

> :set -XFlexibleContexts
> () :: (Fractional Int) => ()

<interactive>:…:1: error:
    • No instance for (Fractional Int)
        arising from an expression type signature
    • In the expression: () :: (Fractional Int) => ()
      In an equation for ‘it’: it = () :: (Fractional Int) => ()

因此您需要使用 lengthInt 的结果从 Float 转换为 fromIntegral。此函数可以返回 Num 中的任何类型,并注意上面 :info Fractional 的输出中 class Num a => Fractional a 表示 FractionalNum 的子集。

> :type fromIntegral
fromIntegral :: (Integral a,Num b) => a -> b

> fromIntegral (length "abc") :: Float
3.0

换句话说,您可以改写 1 / fromIntegral (length xs2)。注意括号!这导致我们看到接下来的几条错误消息:

main.hs:4:62: error:
• Couldn't match expected type ‘[Int] -> Int’
              with actual type ‘Float’
• The function ‘fun2’ is applied to three arguments,but its type ‘[Int] -> [Int] -> Float’ has only two
  In the second argument of ‘(+)’,namely ‘fun2 tail xs1 xs2’
  …

当您编写 fun2 tail xs1 xs2 时,这意味着“将 fun2 应用于三个参数:tailxs1xs2”。您想将 tail xs1 的结果作为单个参数传递,因此您需要括号将它们组合在一起,即 fun2 (tail xs1) xs2。这也是下一个错误的原因:

main.hs:4:67: error:
• Couldn't match expected type ‘[Int]’
              with actual type ‘[a0] -> [a0]’
• Probable cause: ‘tail’ is applied to too few arguments
  In the first argument of ‘fun2’,namely ‘tail’
  In the second argument of ‘(+)’,namely ‘fun2 tail xs1 xs2’
  …

tail[a] -> [a] 类型的函数,但您将它作为 fun2 的第一个参数传递,其第一个参数是 [Int] 类型的值。由于 fun2 的其他调用中的相同错误,相同的错误消息重复出现。

例如,下一个表达式应为 fun2 xs1 (tail xs2)。下一个错误也有相同的根本原因,另外还为您提供了有关如何解决它的好提示:

main.hs:6:10: error:
• Couldn't match expected type ‘[Int] -> Float’
              with actual type ‘Float’
• The function ‘fun2’ is applied to three arguments,but its type ‘[Int] -> [Int] -> Float’ has only two
  In the expression: fun2 tail xs1 xs2
  …

最后,main 必须是 IO 操作,通常为 IO ()。它可能返回任何类型的结果,也就是说,您可以将 IO t 用于任何类型的 t,结果值将被简单地丢弃。但是,您当前传递的是 Float,这是调用 fun2 的结果,因此不匹配:

main.hs:8:1: error:
• Couldn't match expected type ‘IO t0’ with actual type ‘Float’
• In the expression: main
  When checking the type of the IO action ‘main’

解决办法是使用一个IO动作,比如print (fun2 [1,2,3,4] [3,4,5,6]),它等价于putStrLn (show (fun2 [1,6])),两者都会将Float转换为{{1} } 使用调试转储类 String,并返回一个 Show 操作,该操作将在执行 IO 时将结果打印到标准输出。

GHC 的错误消息并不总是完美的,但幸运的是,所有这些错误消息都包含足够的信息来解决您的问题。您只需要更多练习阅读它们并理解它们在说什么以及如何继续。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?