Haskell不明确的事件 - 如何避免?

时间:2010-01-31 22:24:56

标签: haskell map

我在GHCI中执行以下操作:

:m + Data.Map
let map = fromList [(1, 2)]
lookup 1 map

GHCI知道map是(Map Integer Integer)。那么为什么它在Prelude.lookup和Data.Map.lookup之间声明模糊,当类型清楚时我可以避免吗?

<interactive>:1:0:
    Ambiguous occurrence `lookup'
    It could refer to either `Prelude.lookup', imported from Prelude
                          or `Data.Map.lookup', imported from Data.Map

> :t map
map :: Map Integer Integer
> :t Prelude.lookup
Prelude.lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
> :t Data.Map.lookup
Data.Map.lookup :: (Ord k) => k -> Map k a -> Maybe a

3 个答案:

答案 0 :(得分:51)

类型明显不同,但Haskell不允许临时重载名称,因此您只能选择一个lookup而不使用前缀。

典型的解决方案是导入Data.Map合格:

> import qualified Data.Map as Map

然后你可以说

> lookup 1 [(1,2), (3,4)]
Just 2
> Map.lookup 1 Map.empty
Nothing

通常,Haskell库要么避免重复使用Prelude中的名称,要么重新使用它们中的一大堆。 Data.Map是其中之一,作者希望您将其导入为合格。

[编辑以包括ephemient的评论]

如果您想使用不带前缀的Data.Map.lookup,则必须隐藏Prelude.lookup,否则会隐式导入:

import Prelude hiding (lookup) 
import Data.Map (lookup)

这有点奇怪,但如果你使用Data.Map.lookup一堆,而你的数据结构都是地图,那么可能会很有用。

答案 1 :(得分:21)

稍微更一般地说,这首先使我感到困惑 - 所以,让我重申并强调Nathan Sanders所说的话:

  

Haskell不允许临时重载名称

默认情况下这是真的,但起初看起来非常明显。 Haskell允许两种样式的polymorphic functions

  • Parametric polymorphism ,它允许函数以结构相同的抽象方式对任意类型进行操作
  • Ad-hoc多态,它允许函数以结构上不同但希望语义相同的方式对任何已定义的类型进行操作

参数多态是Haskell和相关语言中的标准(并且是首选的选择)方法; ad-hoc多态性是大多数其他语言的标准,通过名称如“函数重载”,并且通常通过编写具有相同名称的多个函数来实现。

在Haskell中通过类型类启用Ad-hoc多态,这需要使用所有关联的ad-hoc多态函数定义类,并为要使用的类型显式声明实例通过重载决议。 在实例声明之外定义的函数永远不是ad-hoc多态,即使它们的类型足够明显,引用也是明确的。

因此,当在不同模块中定义多个具有相同名称的非类型类函数时,如果您尝试使用任一函数,则导入两个不合格的模块将导致错误。 Data.ListData.MapData.Set的组合在这方面特别令人震惊,并且因为Pre Data.List的部分由Prelude导出,所以标准做法是(作为Nathan桑德斯说,要始终导入其他合格人员。

答案 2 :(得分:0)

这总是经常发生,使用说明手册中的代码。您可以随时给他们起一个不同的名字。还要提防电子书中嵌入的unicode空间。

   library IEEE;

entity log2 is 
    port ( 
        clock, reset : in bit;
        start        : in bit;
        ready        : out bit;
        N            : in bit_vector(7 downto 0);
        logval       : out bit_vector (3 downto 0)
        );
end entity log2;

architecture log2_arch of log2 is

        component log2_UC 
            port (
                reset, start : in bit;
                clock: in bit;
                ready : out bit;    
                N : in bit_vector(7 downto 0);
                logval: in bit_vector(3 downto 0)
            );
        end component;
        
        component log2_FD
            port (
                clock : in  bit; 
                N : in bit_vector(7 downto 0)
            );
        end component;
        
        signal entry: bit_vector(7 downto 0);
        signal result: bit_vector(3 downto 0);  
    
begin
    
    UC: log2_UC port map (
            reset => reset,
            start => start,
            clock => clock,
            ready => ready,
            N => entry,
            logval => result
    );
    
    FD: log2_FD port map (
        clock => clock,
        N => entry
    );
end architecture;
        
    
entity log2_UC is
    port (
        reset, start : in bit;
        clock: in bit;
        ready : out bit;    
        N : in bit_vector(7 downto 0);
        logval: in bit_vector(3 downto 0)
    );
end entity log2_UC;

architecture log2_UC_arch of log2_UC is
  type state_t is (wait0, x1, x2, fins);
  signal next_state, current_state: state_t;
begin
    process(clock, reset)
    begin 
        if reset='1' then
          current_state <= wait0;

        elsif (clock'event and clock='1') then
          current_state <= next_state;
        end if;
      end process;
    
    next_state <=
    wait0 when (current_state = wait0) and (start = '0') else
    x1    when (current_state = wait0) and (start = '1') else
    x2    when (current_state = x1)    and (logval = "1111") 
    ;
      
    logval  <= "1111" when current_state=x1 else '0';



    Ready <= '1' when current_state=fins else '0';
end log2_UC_arch;


entity log2_FD is 
  port (
    clock : in  bit; 
    N : in bit_vector(7 downto 0)
    ); 
end log2_FD;
 
architecture archi of log2_FD is 
  signal reg: bit_vector(7 downto 0); 
  signal logval:  bit_vector(3 downto 0);
  signal ready:  bit;
  
  begin 
    process (clock) 
      begin 
        for i in 0 to 7 loop 
            reg(i) <= N(i); 

        logval <= "1111"; 
        ready <= '0';
        
        for i in 0 to 7 loop
            nor reg(i) <= '0';
        end loop;

        if (clock'event and clock='1') then 
          for i in 7 downto 0 loop 
            reg(i) <= reg(i-1); 
            logval <= logval + 1;
          end loop; 
        end if; 
    end process;
end archi;