haskell 查找两个列表之间相似性的程序
haskell program to find the similarity between two lists
好的,所以我是 Haskell 的新手,我想编写一个程序,在其中获取两个列表并找出它们之间的相似性(共同 items/number 项的数量)。
这是我目前所拥有的:
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
return 一个 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) => ()
因此您需要将 length
的结果从 Int
转换为带有 fromIntegral
的 Float
。此函数可以 return Num
中的任何类型,并注意上面 :info Fractional
的输出中 class Num a => Fractional a
意味着 Fractional
是 [= 的子集31=].
> :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
应用于三个参数:tail
、xs1
和 xs2
”。您希望将 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’
• <strong>The function ‘fun2’ is applied to three arguments,
but its type ‘[Int] -> [Int] -> Float’ has only two</strong>
In the expression: fun2 tail xs1 xs2
…
最后,main
必须是一个 IO
动作,通常是 IO ()
。它可能 return 任何类型的结果,也就是说,您可以对任何类型 t
使用 IO 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,2,3,4] [3,4,5,6]))
,两者都会将Float
转换为String
使用调试转储 class Show
和 return 一个 IO
操作,它将在执行 main
时将结果打印到标准输出。
GHC 的错误消息并不总是完美的,但幸运的是,所有这些错误消息都包含足够的信息来解决您的问题。您只需要更多练习阅读它们并理解他们在说什么以及如何进行。
好的,所以我是 Haskell 的新手,我想编写一个程序,在其中获取两个列表并找出它们之间的相似性(共同 items/number 项的数量)。 这是我目前所拥有的:
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
return 一个 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) => ()
因此您需要将 length
的结果从 Int
转换为带有 fromIntegral
的 Float
。此函数可以 return Num
中的任何类型,并注意上面 :info Fractional
的输出中 class Num a => Fractional a
意味着 Fractional
是 [= 的子集31=].
> :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
应用于三个参数:tail
、xs1
和 xs2
”。您希望将 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’ • <strong>The function ‘fun2’ is applied to three arguments, but its type ‘[Int] -> [Int] -> Float’ has only two</strong> In the expression: fun2 tail xs1 xs2 …
最后,main
必须是一个 IO
动作,通常是 IO ()
。它可能 return 任何类型的结果,也就是说,您可以对任何类型 t
使用 IO 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,2,3,4] [3,4,5,6]))
,两者都会将Float
转换为String
使用调试转储 class Show
和 return 一个 IO
操作,它将在执行 main
时将结果打印到标准输出。
GHC 的错误消息并不总是完美的,但幸运的是,所有这些错误消息都包含足够的信息来解决您的问题。您只需要更多练习阅读它们并理解他们在说什么以及如何进行。